Comparison of data writing speed between AF_UNIX and 127.0.0.1 (AF_INET) loopback address (2)

I wrote a blog before: Comparison of data writing speeds between AF_UNIX and 127.0.0.1 (AF_INET) loopback addresses
Then we used the sending end to read a large file, and the receiver received and saved it as a file for testing. It was found that AF_UNIX is not better than the 127.0.0.1 (AF_INET) loopback address. If the number of bytes sent in a single time is small, The loopback address is actually faster.

Since the file sent during the test was 1.15G in size, the sending was completed relatively quickly, and reading and writing files is a relatively time-consuming operation. Considering the time-consuming impact of reading and writing files, I decided to construct the string on the sending end by itself, and receive The method only counts the number of characters received and does not write files. Then the sender sends for 100 seconds, and compares the number of bytes received by AF_UNIX and the return address within 100 seconds.

AF_UNIX server code (unixsocketserver2.c)

#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
 
#defineMAXLINE 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;
\t
    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);
    }
\t
long long allrecvbyte = 0;
 
    memset( & amp;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 *) & amp;serun, size) < 0) {<!-- -->
        perror("bind error");
        exit(1);
    }
    printf("UNIX domain socket bound\\
");
      
    if (listen(listenfd, 20) < 0) {<!-- -->
        perror("listen error");
        exit(1);
    }
    printf("Accepting connections ...\\
");
 
    cliun_len = sizeof(cliun);
    if ((connfd = accept(listenfd, (struct sockaddr *) & amp;cliun, & amp;cliun_len)) < 0){<!-- -->
        perror("accept error");
        goto end;
    }
\t
time_t now, endtime;
now = time(NULL);
    while(1)
{<!-- -->
FD_ZERO( & amp;readmask);
FD_ZERO( & amp;exceptmask);
FD_SET(connfd, & amp;readmask);
FD_SET(connfd, & amp;exceptmask);
tv.tv_sec = 3;
tv.tv_usec = 0;
nready = select(maxfd, & amp;readmask, NULL, & amp;exceptmask, & amp;tv);
if(nready < 0)
{<!-- -->
goto end;
}

if(nready == 0)
{<!-- -->
printf("nready == 0\\
");
continue;
}
\t\t
if(FD_ISSET(connfd, & amp;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;
}
}
\t\t
if(FD_ISSET(connfd, & amp;exceptmask))
{<!-- -->
printf("select, exceptmask\\
");
goto end;
}
}
end:
endtime = time(NULL);
printf("costs %d seconds, allrecvbyte is %lld\\
", endtime - now, allrecvbyte);
close(connfd);
    close(listenfd);
    return 0;
}



AF_UNIX client code (unixsocketclient2.c)

#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>


#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);
    }
      
    // Generally, the bind function is called explicitly so that the server can distinguish between different clients.
    memset( & amp;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 *) & amp;cliun, len) < 0) {<!-- -->
        perror("bind error");
        exit(1);
    }
 
    memset( & amp;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 *) & amp;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;
\t\t
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\\
", allsendbyte);
close(sockfd);
    return 0;
}


Loopback address server code (loopaddrserver2.c)

#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#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);
\t
long long allrecvbyte = 0;
 
    struct sockaddr_in serv_addr;
    memset( & amp;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*) & amp;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*) & amp;clnt_addr, & amp;clnt_addr_size);
time_t now, endtime;
now = time(NULL);
    while(1)
{<!-- -->
FD_ZERO( & amp;readmask);
FD_ZERO( & amp;exceptmask);
FD_SET(clnt_sock, & amp;readmask);
FD_SET(clnt_sock, & amp;exceptmask);
tv.tv_sec = 3;
tv.tv_usec = 0;
nready = select(maxfd, & amp;readmask, NULL, & amp;exceptmask, & amp;tv);
if(nready < 0)
{<!-- -->
goto end;
}

if(nready == 0)
{<!-- -->
printf("nready == 0\\
");
continue;
}
\t\t
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;
}
}
\t\t
if(FD_ISSET(clnt_sock, & amp;exceptmask))
{<!-- -->
printf("select, exceptmask\\
");
goto end;
}
}
end:
endtime = time(NULL);
printf("costs %d seconds, allrecvbyte is %lld\\
", endtime - now, allrecvbyte);
    close(clnt_sock);
    close(serv_sock);
    return 0;
}


Loopback address client code (loopaddrclient2.c)

#include<sys/socket.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<string.h>
#include <errno.h>
#include <stdlib.h>

#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( & amp;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*) & amp;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\\
", allsendbyte);
    close(sock);
    return 0;
}

Test Results:
When the number of bytes sent in a single time is 10,000, the number of bytes received by AF_UNIX is 30240650000, and the number of bytes received by 127.0.0.1 (AF_INET) is 36394910000.

When the number of bytes sent in a single time is 100000, the number of bytes received by AF_UNIX is 40230300000, and the number of bytes received by 127.0.0.1 (AF_INET) is 38364400000.

When the number of bytes sent in a single time is 1000000, the number of bytes received by AF_UNIX is 41368000000, and the number of bytes received by 127.0.0.1 (AF_INET) is 42221000000.

It can be seen that AF_UNIX has no obvious advantage over the loopback address.