美文网首页
unix套接字

unix套接字

作者: 123archu | 来源:发表于2017-11-30 19:12 被阅读0次

    unix套接字常识点

    性能

    很多时候,我们用本机进程间通信时,会使用本地套接字unix socket来通信。
    本地套接字少了网络头、检验码等等一系列的东西,函数调用也没那么深,所以性能很高,在本地,使用unix socket+字节流,比tcp本地回路快两倍左右。使用unix socket+数据报,比udp本地回环快10%左右。

    缓冲区大小

    对于 unix domain socket,设置 SO_SNDBUF 会影响 sendto 最大的报文长度,但是任何针对 SO_RCVBUF 的设置都是无效的 。实际上 unix socket的数据报还是得将数据放入内核所申请的内存块里面,再由另一个进程通过 recvfrom 从内核读取,因此具体可以发送的数据报长度受限于内核的 slab 策略 。在linux平台下,unix socket的数据报一般最大能发128kb,远大于udp的65536字节。

    数据报是否可靠

    unix domain socket 的数据报既不会丢失也不会乱序 。不过kernel 2.6.4 之后,仍然又提供了一个保证次序的类型 “ SOCK_SEQPACKET ”

    数据报缓冲队列长度

    有几个因素会影响缓冲队列的长度,一个是上面提到的 slab 策略,另一个则是系统的内核参数 /proc/sys/net/unix/max_dgram_qlen。缓冲队列长度是这二者共同决定的。


    阻塞实验

    接收方处理不过来的时候,unix socket也会阻塞住的,所以用来非关键路径的本地通信时,要注意这一点,最好设置成非阻塞,或者加比较短的超时
    下面是测试程序,使用unix socket+数据报,client每10ms发一个请求,svr每500ms才处理一个请求

    svr:

    include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/un.h>
    
    char * server_filename = "/tmp/socket-server";
    
    int main(void)
    {
        int s;
        struct sockaddr_un srv_un = {0};
    
        if ((s = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) {
            perror("socket server");
            exit(1);
        }   
    
        srv_un.sun_family = AF_UNIX;
        strncpy(srv_un.sun_path, server_filename, sizeof(srv_un.sun_path));
    
        unlink(srv_un.sun_path);
    
        if (bind(s, (struct sockaddr *)&srv_un, sizeof(srv_un)) == -1) {
            perror("bind server");
            exit(1);
        }   
        socklen_t addre_len;
        struct sockaddr_un remote_un = {0};
        int ret;
        int i =0; 
        char buf[1024] = {0};
        for(;;) {
            ++i;
            memset(buf, 0, sizeof(buf));
            ret = recvfrom(s, buf, sizeof(buf), 0,
                    (struct sockaddr*)&remote_un, &addre_len);
            if (ret == -1) {
                perror("error when recvfrom, ");
            }   
            printf("%s\n", buf);
            usleep(500000);
        }   
    
        close(s);
    
        return 0;
    }
    

    client:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/un.h>
    #include <fcntl.h>
    
    char * server_filename = "/tmp/socket-server";
    char * client_filename = "/tmp/socket-client";
    
    int main(void)
    {
    
        int s;
        char obuf[100];
        struct sockaddr_un srv_un, cli_un = { 0 };
    
        srv_un.sun_family = AF_UNIX;
        strncpy(srv_un.sun_path, server_filename, sizeof(srv_un.sun_path));
    
        cli_un.sun_family = AF_UNIX;
        strncpy(cli_un.sun_path, client_filename, sizeof(cli_un.sun_path));
        unlink(cli_un.sun_path);
    
        if ((s = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) {
            perror("socket server");
            exit(1);
        }
    
        //int val = fcntl(s,F_GETFL,0);
        //fcntl(s,F_SETFL,val|O_NONBLOCK); 设置为非阻塞
    
        if (bind(s, (struct sockaddr *)&cli_un, sizeof(cli_un)) == -1) {
            perror("bind client");
            exit(1);
        }
    
    
        int i = 0;
        while (1) {
            ++i;
            usleep(1000); //1ms
    
            sprintf(obuf, "%d",i);
            if (sendto(s, obuf, strlen(obuf), 0,
                        (struct sockaddr *)&srv_un, sizeof(srv_un)) == -1) {
                perror("send");
                exit(1);
            }
            printf("%d \n", i);
    
        }
        printf("Sent successfully.\n");
        close(s);
    
        return 0;
    }
    

    在我的机器上,发送第12个报文之后,就出现阻塞了。

    如果套接字设置为非阻塞,发生阻塞时,就会返回错误,可以看到打完12之后,就报错了
    非阻塞的client运行结果

    1 
    2 
    3 
    4 
    5 
    6 
    7 
    8 
    9 
    10 
    11 
    12 
    send: Resource temporarily unavailable
    

    相关文章

      网友评论

          本文标题:unix套接字

          本文链接:https://www.haomeiwen.com/subject/rbkbbxtx.html