有一种TCP处理方式是,有一个进程专门来复制端口的监听,然后将接收到得tcp连接交由其余的进程来处理,那么这里就涉及到了文件描述符的传递问题了。。。其实实现也很简单,无非就是accept进程向另外的进程发送一些消息,让它的文件描述表中生成新的一项,然后指向刚刚接受的文件描述符表项就可以了。。。同时监听进程也可以close掉刚刚接收的文件描述符,因为已经有新的进程接管了。。。。
这里记录代码:
#include "../core/core.h" int send_fd(int sock, int fd) { struct iovec iov[1]; char c = 0; iov[0].iov_base = &c; iov[0].iov_len = 1; int cmsgsize = CMSG_LEN(sizeof(int)); struct cmsghdr* cmptr = (struct cmsghdr*)malloc(cmsgsize); if(cmptr == NULL){ return -1; } cmptr->cmsg_level = SOL_SOCKET; cmptr->cmsg_type = SCM_RIGHTS; // we are sending fd. cmptr->cmsg_len = cmsgsize; struct msghdr msg; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = cmptr; msg.msg_controllen = cmsgsize; *(int *)CMSG_DATA(cmptr) = fd; int ret = sendmsg(sock, &msg, 0); free(cmptr); if (ret == -1){ return -1; } return 0; } int recv_fd(int sock) { int cmsgsize = CMSG_LEN(sizeof(int)); struct cmsghdr* cmptr = (struct cmsghdr*)malloc(cmsgsize); if (cmptr == NULL) { return -1; } char buf[32]; // the max buf in msg. struct iovec iov[1]; iov[0].iov_base = buf; iov[0].iov_len = sizeof(buf); struct msghdr msg; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = cmptr; msg.msg_controllen = cmsgsize; int ret = recvmsg(sock, &msg, 0); free(cmptr); if (ret == -1) { return -1; } int fd = *(int *)CMSG_DATA(cmptr); return fd; }