• AF_UNIX和127.0.0.1(AF_INET)回环地址写数据速度对比(二)


    之前写了篇博客:AF_UNIX和127.0.0.1(AF_INET)回环地址写数据速度对比
    然后利用的是发送端读取大文件,接收方接收并保存为文件的方式进行测试,结果发现,AF_UNIX并未比127.0.0.1(AF_INET)回环地址优秀,若单次发送的字节数少时,回环地址反而更快。

    由于测试时发送的是1.15G大小的文件,比较快就发送结束了,而且读文件,写文件是个比较费时的操作,本人考虑到读写文件费时的影响,决定发送端自己构造字符串,接收方只统计接收到的字符个数,并不写文件。然后发送端发送100秒,对比下100秒之内,AF_UNIX和回还地址接收到的字节个数。

    AF_UNIX服务端代码(unixsocketserver2.c)

    #include   
    #include   
    #include   
    #include   
    #include   
    #include   
    #include   
    #include   
    #include    
     
    #define MAXLINE 80  
     
    char *socket_path = "/tmp/server.socket";  
    
    #define RECV_LEN 1000000
     
    int main(void)  
    {  
    	fd_set readmask, exceptmask;
    	struct timeval tv;
    	int maxfd = FD_SETSIZE;
    	int nready = 0;
    	char buf[RECV_LEN + 1];
    	int readbyte, writebyte;
    	
        struct sockaddr_un serun, cliun;  
        socklen_t cliun_len;  
        int listenfd, connfd, size;  
     
        if ((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {  
            perror("socket error");  
            exit(1);  
        }  
    	
    	long long allrecvbyte = 0;
     
        memset(&serun, 0, sizeof(serun));  
        serun.sun_family = AF_UNIX;  
        strcpy(serun.sun_path, socket_path);  
        size = offsetof(struct sockaddr_un, sun_path) + strlen(serun.sun_path);  
        unlink(socket_path);  
        if (bind(listenfd, (struct sockaddr *)&serun, size) < 0) {  
            perror("bind error");  
            exit(1);  
        }  
        printf("UNIX domain socket bound\n");  
          
        if (listen(listenfd, 20) < 0) {  
            perror("listen error");  
            exit(1);          
        }  
        printf("Accepting connections ...\n");  
     
        cliun_len = sizeof(cliun);         
        if ((connfd = accept(listenfd, (struct sockaddr *)&cliun, &cliun_len)) < 0){  
            perror("accept error");  
            goto end;  
        }
    	
    	time_t now, endtime;
    	now = time(NULL);
        while(1)
    	{
    		FD_ZERO(&readmask);
    		FD_ZERO(&exceptmask);
    		FD_SET(connfd, &readmask);
    		FD_SET(connfd, &exceptmask);
    		tv.tv_sec = 3;
    		tv.tv_usec = 0;
    		nready = select(maxfd, &readmask, NULL, &exceptmask, &tv);
    		if(nready < 0)
    		{
    			goto end;
    		}
    
    		if(nready == 0)
    		{
    			printf("nready == 0\n");
    			continue;
    		}
    		
    		if(FD_ISSET(connfd, &readmask))
    		{
    			readbyte = recv(connfd, buf, RECV_LEN, 0);
    			if(readbyte < 0)
    			{
    				perror("readbyte < 0");
    				goto end;
    			}
    			if(readbyte == 0)
    			{
    				perror("readbyte == 0");
    				goto end;
    			}
    			if(readbyte > 0)
    			{
    				allrecvbyte += readbyte;
    			}
    		}
    		
    		if(FD_ISSET(connfd, &exceptmask))
    		{
    			printf("select, exceptmask\n");
    			goto end;
    		}
    	}  
    end:
    	endtime = time(NULL);
    	printf("costs %d seconds, allrecvbyte is %lld\n", endtime - now, allrecvbyte);
    	close(connfd);
        close(listenfd);  
        return 0;  
    }
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116

    AF_UNIX客户端代码(unixsocketclient2.c)

    #include   
    #include   
    #include   
    #include   
    #include   
    #include   
    #include   
    #include   
    
    
    #define SEND_LEN 1000000
     
    char *client_path = "/tmp/client.socket";  
    char *server_path = "/tmp/server.socket";  
     
    int main() {  
        struct  sockaddr_un cliun, serun;  
        int len;   
        int sockfd, n;  
    	int i = 0;
     
        if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){  
            perror("client socket error");  
            exit(1);  
        }  
          
        // 一般显式调用bind函数,以便服务器区分不同客户端  
        memset(&cliun, 0, sizeof(cliun));  
        cliun.sun_family = AF_UNIX;  
        strcpy(cliun.sun_path, client_path);  
        len = offsetof(struct sockaddr_un, sun_path) + strlen(cliun.sun_path);  
        unlink(cliun.sun_path);  
        if (bind(sockfd, (struct sockaddr *)&cliun, len) < 0) {  
            perror("bind error");  
            exit(1);  
        }  
     
        memset(&serun, 0, sizeof(serun));  
        serun.sun_family = AF_UNIX;  
        strcpy(serun.sun_path, server_path);  
        len = offsetof(struct sockaddr_un, sun_path) + strlen(serun.sun_path);  
        if (connect(sockfd, (struct sockaddr *)&serun, len) < 0){  
            perror("connect error");  
            exit(1);  
        }  
     
        int sendbyte = 0;
        int alreadysendbyte = 0;
    	long long allsendbyte = 0;
        char buf[SEND_LEN + 1];
    	time_t begin = time(NULL);
    	time_t now = time(NULL);
    	int continueSeconds = 0;
        while(continueSeconds < 100)
    	{
    		alreadysendbyte = 0;
    		for(i = 0; i < SEND_LEN; i++)
    		{
    			buf[i] = i + 1;
    		}
    		n = SEND_LEN;
    		
    		sendbyte = send(sockfd, buf, n, 0);
    		if(sendbyte == -1)
    		{
    			perror("send error");
    			goto end;
    		}
            alreadysendbyte += sendbyte;
            while(alreadysendbyte < n)
            {
    			sendbyte = send(sockfd, buf + alreadysendbyte, n - alreadysendbyte, 0);
    			if(sendbyte == -1)
                {
    				perror("send error");
    				goto end;
    			}
    			alreadysendbyte += sendbyte;
    		}
    		allsendbyte += n;
    		now = time(NULL);
    		continueSeconds = now - begin;
    	}
    end:
    	printf("allsendbyte is %lld\n", allsendbyte);
    	close(sockfd);
        return 0;  
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90

    回环地址服务端代码(loopaddrserver2.c)

    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define RECV_LEN 1000000
    
    int main(){
    	fd_set readmask, exceptmask;
    	struct timeval tv;
    	int maxfd = FD_SETSIZE;
    	int nready = 0;
    	char buf[RECV_LEN + 1];
    	int readbyte, writebyte;
        int serv_sock=socket(AF_INET,SOCK_STREAM,0);
    	
    	long long allrecvbyte = 0;
     
        struct sockaddr_in serv_addr;
        memset(&serv_addr,0,sizeof(serv_addr));
        serv_addr.sin_family=AF_INET;
        serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
        serv_addr.sin_port=htons(9990);
     
        bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
     
        listen(serv_sock,5);
     
        struct sockaddr_in clnt_addr;
        socklen_t clnt_addr_size=sizeof(clnt_addr);
        int clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_addr,&clnt_addr_size);
    	time_t now, endtime;
    	now = time(NULL);
        while(1)
    	{
    		FD_ZERO(&readmask);
    		FD_ZERO(&exceptmask);
    		FD_SET(clnt_sock, &readmask);
    		FD_SET(clnt_sock, &exceptmask);
    		tv.tv_sec = 3;
    		tv.tv_usec = 0;
    		nready = select(maxfd, &readmask, NULL, &exceptmask, &tv);
    		if(nready < 0)
    		{
    			goto end;
    		}
    
    		if(nready == 0)
    		{
    			printf("nready == 0\n");
    			continue;
    		}
    		
    		if(FD_ISSET(clnt_sock, &readmask))
    		{
    			readbyte = recv(clnt_sock, buf, RECV_LEN, 0);
    			if(readbyte < 0)
    			{
    				perror("readbyte < 0");
    				goto end;
    			}
    			if(readbyte == 0)
    			{
    				perror("readbyte == 0");
    				goto end;
    			}
    			if(readbyte > 0)
    			{
    				allrecvbyte += readbyte;
    			}
    		}
    		
    		if(FD_ISSET(clnt_sock, &exceptmask))
    		{
    			printf("select, exceptmask\n");
    			goto end;
    		}
    	}
    end: 
    	endtime = time(NULL);
    	printf("costs %d seconds, allrecvbyte is %lld\n", endtime - now, allrecvbyte);
        close(clnt_sock);
        close(serv_sock);
        return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88

    回环地址客户端代码(loopaddrclient2.c)

    #include
    #include
    #include
    #include
    #include 
    #include 
    
    #define SEND_LEN 1000000
    
    int main(){
    
        int sock=socket(AF_INET,SOCK_STREAM,0);  
    
    	int n = 0;
    	int i = 0;
        struct sockaddr_in serv_addr;
        memset(&serv_addr,0,sizeof(serv_addr));
        serv_addr.sin_family=AF_INET;
        serv_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
        serv_addr.sin_port=htons(9990);
    
        if(connect(sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) < 0)
    	{
    		perror("connect failed");
    		goto end;
    	}
        int sendbyte = 0;
        int alreadysendbyte = 0;
    	long long allsendbyte = 0;
        char buf[SEND_LEN + 1];
    	time_t begin = time(NULL);
    	time_t now = time(NULL);
    	int continueSeconds = 0;
        while(continueSeconds < 100)
    	{
    		alreadysendbyte = 0;
    		for(i = 0; i < SEND_LEN; i++)
    		{
    			buf[i] = i + 1;
    		}
    		n = SEND_LEN;
    		sendbyte = send(sock, buf, n, 0);
    		if(sendbyte == -1)
    		{
    			perror("send error");
    			goto end;
    		}
            alreadysendbyte += sendbyte;
            while(alreadysendbyte < n)
            {
    			sendbyte = send(sock, buf + alreadysendbyte, n - alreadysendbyte, 0);
    			if(sendbyte == -1)
                {
    				perror("send error");
    				goto end;
    			}
    			alreadysendbyte += sendbyte;
    		}
    		allsendbyte += n;
    		now = time(NULL);
    		continueSeconds = now - begin;
    	}
    end:
    	printf("allsendbyte is %lld\n", allsendbyte);
        close(sock);
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    测试结果:
    单次send字节数为10000时,AF_UNIX接收字节数为30240650000,127.0.0.1(AF_INET)接收字节数为36394910000。

    单次send字节数为100000时,AF_UNIX接收字节数为40230300000,127.0.0.1(AF_INET)接收字节数为38364400000。

    单次send字节数为1000000时,AF_UNIX接收字节数为41368000000,127.0.0.1(AF_INET)接收字节数为42221000000。

    可见,AF_UNIX比回环地址并无明显优势

  • 相关阅读:
    安装CUDA、anaconda、pytorch
    flink对状态ttl进行单元测试
    力扣(LeetCode)32. 最长有效括号(C++)
    VSCode开发go手记
    大二一个学期学这么点内容,没有概念,只有实操
    [需求管理-4]:需求分析全过程:需求分析+资源评估+项目计划
    can总线隔离中继器、canbridge、CanRepeater的can波特率和滤波设置
    【C语言】文件操作(一)
    基于java+ssm+vue+mysql的网络教学系统
    软件需求文档、设计文档、开发文档、运维文档大全
  • 原文地址:https://blog.csdn.net/tusong86/article/details/133702088