父子进程间通信
#ifndef _PRIV_SOCK_H_ #define _PRIV_SOCK_H_ #include "session.h" ///内部进程自定义协议 //FTP服务进程与noboby进程进行通讯 // FTP服务进程向nobody进程请求的命令 FTP服务进程发送命令 nobody进程根据发送的命令发送对应的应答 #define PRIV_SOCK_GET_DATA_SOCK 1//主动模式相关 #define PRIV_SOCK_PASV_ACTIVE 2//被动模式相关的 #define PRIV_SOCK_PASV_LISTEN 3 #define PRIV_SOCK_PASV_ACCEPT 4 // nobody进程对FTP服务进程的应答 #define PRIV_SOCK_RESULT_OK 1 #define PRIV_SOCK_RESULT_BAD 2 void priv_sock_init(session_t *sess);//初始化内部进程间通信通道 void priv_sock_close(session_t *sess);//关闭内部进程间通信通道 void priv_sock_set_parent_context(session_t *sess);//设置父进程环境 void priv_sock_set_child_context(session_t *sess);//设置子进程环境 void priv_sock_send_cmd(int fd, char cmd);//发送命令(子->父) char priv_sock_get_cmd(int fd);// 接收命令(父<-子) void priv_sock_send_result(int fd, char res);// 发送结果(父->子) char priv_sock_get_result(int fd);//接收结果(子<-父) void priv_sock_send_int(int fd, int the_int);// 发送一个整数 int priv_sock_get_int(int fd);// 接收一个整数 void priv_sock_send_buf(int fd, const char *buf, unsigned int len);///发送一个字符串 void priv_sock_recv_buf(int fd, char *buf, unsigned int len);// 接收一个字符串 void priv_sock_send_fd(int sock_fd, int fd);//发送文件描述符 int priv_sock_recv_fd(int sock_fd);// 接收文件描述符 #endif /* _PRIV_SOCK_H_ */
#include "privsock.h" #include "common.h" #include "sysutil.h" void priv_sock_init(session_t *sess)//初始化内部进程间通信通道 { int sockfds[2];//内部进程间通道的建立 if (socketpair(PF_UNIX, SOCK_STREAM, 0, sockfds) < 0) //创建了一对无名的套接字描述符 和管道类似 ERR_EXIT("socketpair"); sess->parent_fd = sockfds[0];//套接字对 sess->child_fd = sockfds[1]; } void priv_sock_close(session_t *sess) //关闭内部进程间通信通道 { if (sess->parent_fd != -1) //父进程只留下父进程的套接字 { close(sess->parent_fd); sess->parent_fd = -1; } if (sess->child_fd != -1) //子进程只留下子进程的套接字 { close(sess->child_fd);//子进程是不需要父进程的套接字 sess->child_fd = -1; } } void priv_sock_set_parent_context(session_t *sess)//设置父进程环境 { if (sess->child_fd != -1)//父进程只留下父进程的套接字 { close(sess->child_fd); sess->child_fd = -1; } } void priv_sock_set_child_context(session_t *sess)//设置子进程环境 { if (sess->parent_fd != -1)//子进程只留下子进程的套接字 { close(sess->parent_fd);//子进程是不需要父进程的套接字 sess->parent_fd = -1; } } //这四个命令都传送一个字节 void priv_sock_send_cmd(int fd, char cmd) { int ret; ret = writen(fd, &cmd, sizeof(cmd));//这里的套接字是管道的一端 if (ret != sizeof(cmd)) { fprintf(stderr, "priv_sock_send_cmd error ");//做一个提示 exit(EXIT_FAILURE);//退出进程 } } char priv_sock_get_cmd(int fd)// 接收命令(父<-子) nobody进程从服务进程来接收命令 { char res; int ret; ret = readn(fd, &res, sizeof(res)); if (ret == 0) //接收失败 { printf("ftp process exit "); exit(EXIT_SUCCESS); //退出进程 } if (ret != sizeof(res)) { fprintf(stderr, "priv_sock_get_cmd error "); exit(EXIT_FAILURE); } return res; } // 发送结果(父->子) nobody进程向服务进程来发送命令的响应 void priv_sock_send_result(int fd, char res) { int ret; ret = writen(fd, &res, sizeof(res));//这里的套接字是管道的一端 if (ret != sizeof(res))//发送失败 { fprintf(stderr, "priv_sock_send_result error ");//做一个提示 exit(EXIT_FAILURE);//退出进程 } } //接收结果(子<-父) ) FTP服务进程从nobody服务进程接受命令的响应 char priv_sock_get_result(int fd) { char res; int ret; ret = readn(fd, &res, sizeof(res)); if (ret != sizeof(res)) //接收失败 { fprintf(stderr, "priv_sock_get_result error "); exit(EXIT_FAILURE); //退出进程 } return res; } void priv_sock_send_int(int fd, int the_int)// 发送一个整数 { int ret; ret = writen(fd, &the_int, sizeof(the_int)); if (ret != sizeof(the_int)) { fprintf(stderr, "priv_sock_send_int error "); exit(EXIT_FAILURE); } } int priv_sock_get_int(int fd)//接收一个整数 { int the_int; int ret; ret = readn(fd, &the_int, sizeof(the_int)); if (ret != sizeof(the_int)) { fprintf(stderr, "priv_sock_get_int error "); exit(EXIT_FAILURE); } return the_int;//返回接受的内容 } void priv_sock_send_buf(int fd, const char *buf, unsigned int len)//发送一个字符串 { priv_sock_send_int(fd, (int)len); int ret = writen(fd, buf, len);//发送一个长度 if (ret != (int)len) { fprintf(stderr, "priv_sock_send_buf error "); exit(EXIT_FAILURE); } } void priv_sock_recv_buf(int fd, char *buf, unsigned int len)//接收一个字符串 { unsigned int recv_len = (unsigned int)priv_sock_get_int(fd);//这里接受的整数的是字符串的长度 //对于一个不定长的字符串来说,我们要先发送一个字符串长度 if (recv_len > len) { fprintf(stderr, "priv_sock_recv_buf error ");//接受失败 exit(EXIT_FAILURE); } int ret = readn(fd, buf, recv_len);//发送文件描述符 if (ret != (int)recv_len) { fprintf(stderr, "priv_sock_recv_buf error "); exit(EXIT_FAILURE); } } void priv_sock_send_fd(int sock_fd, int fd) { send_fd(sock_fd, fd);//从sock_fd unix域来接受fd文件描述符 } int priv_sock_recv_fd(int sock_fd)//接收文件描述符 { return recv_fd(sock_fd); }
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇:没有了
- 下一篇:没有了