socketpair

    xiaoxiao2021-03-26  4

    socketpair:建立一对匿名的已经连接的套接字

    #include <sys/types.h> #include <sys/socket.h> int socketpair(int d, int type, int protocol, int sv[2]);

    1)UNIX域

    2)SOCK_STREAM SOCK_DGRAM

    3)对于socketpair函数,protocol参数必须提供为0。

    4)参数sv[2]是接收代表两个套接口的整数数组。每一个文件描述符代表一个套接口,并且与另一个并没有区别。

    5)返回值:成功时,返回零。 出错时,返回-1,并适当地设置errno。

    在ProxyManager的分派连接中,调用ProxyWorker中的send函数

    // 分派连接 for (size_t i = 0; i < _workers.size(); ++i) { int ret = _workers[_idx]->send(&fds[0], (int)fds.size()); _idx = (_idx + 1) % (int)_workers.size(); if (ret == 0) { break; } } 在ProxyWorker中,start函数,父进程send,子进程读

    void ProxyWorker::start() { if (_fd != -1) { ::close(_fd); _fd = -1; } int fd[2]; ::socketpair(AF_UNIX, SOCK_STREAM, 0, fd); // 未命名的全双工管道 可以在fd[0] 与 fd[1]间 (父子进程间)完成通讯 if ((_pid = fork()) == 0) { // 子进程 Comm::LogErr("worker %u running", _startId); ::close(fd[0]); _pid = getpid(); { int cpu_num = sysconf(_SC_NPROCESSORS_ONLN) - 1; if (cpu_num > 2){ int cpuidx = (_startId + 1 ) % cpu_num + 1; cpu_set_t mask; CPU_ZERO(&mask); CPU_SET(cpuidx, &mask); sched_setaffinity(_pid, sizeof(mask), &mask); } } _mgr.init(fd[1], _startId, _step); _mgr.run(); Comm::LogErr("worker exit"); _exit(0); } else if (_pid > 0) { // 父进程 ::close(fd[1]); _fd = fd[0]; } else { //Comm::LogErr } } ProxyWorker中的send函数

    int ProxyWorker::send(int* fd, int n) { char c = '\0'; struct iovec iov; iov.iov_base = &c; iov.iov_len = 1; char buf[CMSG_SPACE(sizeof(int) * n)]; struct msghdr msg = { 0 }; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = buf; msg.msg_controllen = sizeof(buf); msg.msg_name = NULL; msg.msg_namelen = 0; struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_len = CMSG_LEN(sizeof(int) * n); memcpy(CMSG_DATA(cmsg), fd, sizeof(int) * n); ssize_t s = ::sendmsg(_fd, &msg, 0); if (s < 0) { Comm::LogErr("sendmsg %ld %s", s, strerror(errno)); return -1; } return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-600414.html

    最新回复(0)