精华内容
下载资源
问答
  • socketpair

    2017-01-17 16:49:13
    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)对于socket...

    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;
    }



    展开全文
  • socketpair_binder

    2016-10-23 22:32:18
    socketpair,binder
  • socketpair机制 描述 先看下传统的CS模型,如下: 总是一方发起请求,等待另一方回应。当一次传输完成之后,client端发起新的请求之后,server端才作出回应。 那如何才能做到双向通信? 一种解决办法就是client...

    socketpair机制

    描述

    先看下传统的CS模型,如下:

     

    总是一方发起请求,等待另一方回应。当一次传输完成之后,client端发起新的请求之后,server端才作出回应。 那如何才能做到双向通信?  一种解决办法就是client端即使client,又是server,server端即使client也是server,如下:

     

    但是上述方面比较复杂,这时候就引入要分析的socketpair了。

     

    socketpair用于创建一对相互连接的unnamed socket。而pipe系统调用使用创建的pipe也是相互连接的unnamed pipe(无名管道)。而pipe和socketpair创建的描述符之间的区别就是:  pipe创建的描述符一端只能用于读,一端用于写,而socketpair创建的描述符任意一端既可以读也可以写。

     

    原理

    示例代码:

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <pthread.h>
     
    #define SOCKET_BUFFER_SIZE      (32768U)
     
     
    void *thread_function(void *arg)
    {
        int len = 0;
        int fd  = *((int*)(arg));
        char buf[500];
        int cnt = 0;
     
        /*主线程*/
        while(1)
        {        
            /*向main thread线程发送数据*/
            len = sprintf(buf, "Hi, main process, cnt = %d", cnt++);
            write(fd, buf, len);
        
            /*读数据*/
            len = read(fd, buf, 500);
            buf[len]='\0';
            printf("%s\n",buf);
            
            sleep(5);    
        } 
        
        return NULL;
    }
     
     
    int main()
    {
        int ret;
        int sockets[2];
        int bufferSize = SOCKET_BUFFER_SIZE;
        pthread_t thread;
        
        ret = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets);
        if(ret == -1)
        {
            printf("socketpair create error!\n");
            return -1;
        }
        
        
        /*设置socket描述符的选项*/
        setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
        setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
        setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
        setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
     
        
        /*创建线程1*/
        pthread_create(&thread, NULL, thread_function, (void*)(&sockets[1]));
     
     
        int len = 0;
        int fd  = sockets[0];
        char buf[500];
        int cnt = 0;
     
        /*主线程*/
        while(1)
        {
            /*读数据*/
            len = read(fd, buf, 500);
            buf[len]='\0';
            printf("%s\n",buf);
            
            /*项thread线程发送数据*/
            len = sprintf(buf, "Hi, thread process, cnt = %d", cnt++);
            write(fd, buf, len);
        }
     
        return 0;
    }

    测试结果:

    1.  编译代码

    gcc socketpair.c -o socketpair -lpthread


    2. 运行,查看结果

    test$ ./socketpair
    
    Hi, main process, cnt = 0
    
    Hi, thread process, cnt = 0
    
    Hi, main process, cnt = 1
    
    Hi, thread process, cnt = 1
    
    Hi, main process, cnt = 2
    
    Hi, thread process, cnt = 2

    注意:  socketpair创建的只适用于父子进程或者线程间通信,不能用于两个进程之间通信。如果要实现两个进程之间的双向通信,则需要将socketpair创建的一个描述符fd发送给另一个进程,这相当于两个两个不同的进程访问同一个文件。

    socketpair和pipe的区别

    (原文:https://blog.csdn.net/fangru/article/details/9041119#

    管道pipe是半双工的,pipe两次才能实现全双工,使得代码复杂。socketpair直接就可以实现全双工。

    socketpair对两个文件描述符中的任何一个都可读和可写,而pipe是一个读,一个写。

    详间代码:

    一:pipe实现父子进程全双工通信:

    #include <stdlib.h>
    #include <stdio.h>
     
    int main ()
    {
        int fd1[2],fd2[2];
        pipe(fd1);
        pipe(fd2);
        if ( fork() ) {
            /* Parent process: echo client */
            int val = 0;
            close( fd1[0] );
            close(fd2[1]);
            while ( 1 ) {
                sleep( 1 );
                ++val;
                printf( "parent Sending data: %d\n", val );
                write( fd1[1], &val, sizeof(val) );
                read( fd2[0], &val, sizeof(val) );
                printf( "parent Data received: %d\n", val );
            }
        }
        else {
            /* Child process: echo server */
            int val ;
            close( fd1[1] );
            close(fd2[0]);
            while ( 1 ) {
                read( fd1[0], &val, sizeof(val) );
                printf( "son Data received: %d\n", val );
                ++val;
                write( fd2[1], &val, sizeof(val) );
                printf( "son send received: %d\n", val );
            }
        }
    }

    输出结果:parent Sending data: 1 
    son Data received: 1 
    son send received: 2 
    parent Data received: 2 
    parent Sending data: 3 
    son Data received: 3 
    son send received: 4 

    parent Data received: 4

     

    一:soketpair实现父子进程全双工通信:

    #include <sys/types.h>
    #include <sys/socket.h>
     
    #include <stdlib.h>
    #include <stdio.h>
     
    int main ()
    {
        int fd[2];
        int r = socketpair( AF_UNIX, SOCK_STREAM, 0, fd );
        if ( r < 0 ) {
            perror( "socketpair()" );
            exit( 1 );
        }   
        if ( fork() ) {
            /* Parent process: echo client */
            int val = 0;
            close( fd[1] );
            while ( 1 ) {
                sleep( 1 );
                ++val;
                printf( "parent Sending data: %d\n", val );
                write( fd[0], &val, sizeof(val) );
                read( fd[0], &val, sizeof(val) );
                printf( "parent Data received: %d\n", val );
     
            }
        }
        else {
            /* Child process: echo server */
            int val ;
            close( fd[0] );
            while ( 1 ) {
                read( fd[1], &val, sizeof(val) );
                printf( "son Data received: %d\n", val );
                ++val;
                write( fd[1], &val, sizeof(val) );
                printf( "son send received: %d\n", val );
            }
        }
    }

    输出结果:parent Sending data: 1 
    son Data received: 1 
    son send received: 2 
    parent Data received: 2 
    parent Sending data: 3 
    son Data received: 3 
    son send received: 4 

    parent Data received: 4

    更多使用实例:《socketpair的用法和理解》https://blog.csdn.net/weixin_40039738/article/details/81095013

     

    展开全文
  • linux socketpair

    2018-09-08 11:37:00
    相对于无名管道来说,socketpair也是使用在亲缘进程之间,不过它提供了能够全双工通信的通道 man socketpair: #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int socket...

    相对于无名管道来说,socketpair也是使用在亲缘进程之间,不过它提供了能够全双工通信的通道

    man socketpair:

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

      该sv保存的两个文件描述符,能写也能读

    #include <stdio.h>
    #include <errno.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <sys/socket.h>
    
    int main()
    {
        int sockfd[2] = {0};
    
        if (-1 == socketpair(PF_UNIX, SOCK_STREAM, 0, sockfd))
        {
            fprintf(stderr, "socketpair: %d, %s\n", errno, strerror(errno));
            exit(1);
        }
    
        pid_t pid = fork();
    
        if (pid < 0)
        {
            fprintf(stderr, "fork: %d, %s\n", errno, strerror(errno));
            exit(1);
        }
        if (pid == 0)
        {
            close(sockfd[1]);
            char buf[] = "data from child program";
            write(sockfd[0], buf, strlen(buf));
    
            char szRecv[200] = {0};
            read(sockfd[0], szRecv, 200);
            printf("in child program, get data: %s\n", szRecv);
            
            close(sockfd[0]);
        }
        else
        {
            close(sockfd[0]);
    
            char szRecv[200] = {0};
            read(sockfd[1], szRecv, 200);
            printf("in parent program, get data: %s\n", szRecv);
    
            char buf[] = "data from parent program";
            write(sockfd[1], buf, strlen(buf));
    
            close(sockfd[1]);
            wait(NULL);
        }
        
    	return 0;
    }
    

      

    转载于:https://www.cnblogs.com/zuofaqi/p/9608638.html

    展开全文
  • 主要为大家详细介绍了Android socketpair双向通信的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 78-socketpair 函数

    千次阅读 2017-05-05 10:59:14
    如果涉及到父子进程间的通信,我们就没有必要弄的那么麻烦,不...1. socketpair 函数int socketpair(int family, int protocol, int sockfd[2]);family 参数只能是 AF_LOCAL 或 AF_UNIX,protocol 只能是 0. type 参数

    如果涉及到父子进程间的通信,我们就没有必要弄的那么麻烦,不需要再创建套接字地址,不需要绑定。函数 socketpair 会创建两个连接好的套接字。

    1. socketpair 函数

    int socketpair(int family, int protocol, int  sockfd[2]);

    family 参数只能是 AF_LOCAL 或 AF_UNIX,protocol 只能是 0. type 参数既可以是 SOCK_STREAM,也可以是 SOCK_DGRAM.

    将 type 指定为 SOCK_STREAM 得到的结果称为流管道(stream pipe),它和 pipe 创建的普通 unix 管道非常像,只不过,stream pipe 是全双工的。所以使用起来,它比 pipe 函数更加方便。

    2. 示例

    下面是使用 socketpair 函数用于父子进程通信的伪代码:

    int main() {
      int nr, pid, sockfd[2];
      char buf[4096];
      socketpair(AF_LOCAL, 0, sockfd);
      pid = fork();
      if (pid == 0) {
        // 子进程关闭 0 号描述符,因为它只使用 1close(sockfd[0]);
        nr = read(sockfd[1], buf, 4096);
        write(STDOUT_FILENO, buf, nr);
        exit(0);
      }
    
      // 父进程关闭 1 号描述符,它只使用 0 号。
      close(sockfd[1]);
      // 父进程向流管道写入数据
      write(sockfd[0], "hello", 5);
      waitpid(pid, NULL, 0);
      return 0;
    }

    3. 使用 socketpair 的案例

    3.1 程序路径

    git clone https://git.oschina.net/ivan_allen/unp.git

    如果你已经 clone 过这个代码了,请使用 git pull 更新一下。本节程序所使用的程序路径是 unp/program/unixdomainprotocols/sockpair.

    3.2 程序说明

    在此路径下有两个程序,分别是 main 和 upper. upper 函数从标准输入读取数据,转换成大写后输出到标准输出。

    main 程序从标准输入读取数据,并 fork 一个子进程,该子进程 exec upper 程序后,将数据写入到 upper 程序的标准输入,然后再从 upper 程序的标准输出读取数据,打印到屏幕。

    这两个程序的数据传输如图 1.


    这里写图片描述
    图1 main 和 upper 的数据传输

    这个程序的难点在于,main 程序 fork exec 后,如何向 upper 的标准输入与输出写数据和读数据。其实很简单,使用 dup2 函数重新定向描述符即可。

    我们把 main 和 upper 这种关系称之为协作,下面是伪代码。

    socketpair(AF_LOCAL, 0, sockfd[2]);
    pid = fork();
    if (pid == 0) {
       close(sockfd[0]);
       // 将 sockfd[1] 复制一份,让 STDIN_FILENO 也指向它
       dup2(sockfd[1], STDIN_FILENO);
       dup2(sockfd[1], STDOUT_FILENO);
       execl("upper", "upper", NULL);
       exit(1);
    }
    
    // 父进程
    
    close(sockfd[1]);
    
    // read and write sockfd[0]...

    3.3 运行结果


    这里写图片描述
    图2 程序运行结果

    4. 总结

    • 掌握 socketpair 的用法
    展开全文
  • Linux socketpair详解

    千次阅读 2015-03-24 22:11:11
    socketpair函数概要如下: #include 定义一些C宏常量 #include 定义socketpair函数原型 int socketpair(int domain, int type, int protocol, int sv[2]); socketpair函数需要四个参数: domain-套接口的域 ...
  • socket通信socketpair

    千次阅读 2013-05-08 12:59:10
    这篇文章主要介绍的是socketpair()函数,至于函数的详细介绍,大家可以参看:man socketpair 介绍的还是可以的。下面是中文简介: 函数原型 #include #include int socketpair(int d, int type, int protocol,...
  • socketpair函数用法

    2021-03-28 15:48:48
    socketpair()函数的声明: #include <sys/types.h> #include <sys/socket.h> int socketpair(int d, int type, int protocol, int sv[2]); socketpair()函数用于创建一对无名的、相互连接的套接子。 ...
  • socketpair理解

    2015-12-15 20:34:13
    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。... 今天跟人谈到socketpair... 先说说我的理解:socketpair创建了一对无名的套接字描述符(只能在AF_UNI
  • socketpair 使用

    2021-03-24 21:24:15
    #include <unistd.h> #include <iostream> #include <sys/socket.h> #include <string.h> using namespace std;... if(socketpair(AF_UNIX,SOCK_STREAM,0,sv)<0) { perror("sock.
  • socket通信之socketpair

    千次阅读 2012-10-05 18:04:44
    这篇文章主要介绍的是socketpair()函数,至于函数的详细介绍,大家可以参看:man socketpair 介绍的还是可以的。下面是中文简介: 函数原型 #include #include int socketpair(int d, int type, int protocol,...
  • linux下socketpair通信

    2019-07-02 16:31:24
    函数原型: #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int socketpair(int domain, int type, int protocol, int sv[2]); 函数功能描述: ...socketpair函数创建...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,411
精华内容 7,364
关键字:

socketpair