1 // SPDX-License-Identifier: GPL-2.0
6 #include <netinet/in.h>
7 #include <netinet/tcp.h>
11 #include <sys/socket.h>
17 static unsigned long timediff(struct timeval s
, struct timeval e
)
19 unsigned long s_us
, e_us
;
21 s_us
= s
.tv_sec
* 1000000 + s
.tv_usec
;
22 e_us
= e
.tv_sec
* 1000000 + e
.tv_usec
;
28 static void client(int port
)
31 struct sockaddr_in addr
, laddr
;
32 socklen_t len
= sizeof(laddr
);
36 struct timeval start
, end
;
37 unsigned long lat
, sum_lat
= 0, nr_lat
= 0;
40 gettimeofday(&start
, NULL
);
42 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
44 error(-1, errno
, "socket creation");
48 if (setsockopt(sock
, SOL_SOCKET
, SO_LINGER
, &sl
, sizeof(sl
)))
49 error(-1, errno
, "setsockopt(linger)");
51 if (setsockopt(sock
, IPPROTO_TCP
, TCP_NODELAY
,
53 error(-1, errno
, "setsockopt(nodelay)");
55 addr
.sin_family
= AF_INET
;
56 addr
.sin_port
= htons(port
);
58 if (inet_pton(AF_INET
, "127.0.0.1", &addr
.sin_addr
) <= 0)
59 error(-1, errno
, "inet_pton");
61 if (connect(sock
, (struct sockaddr
*)&addr
, sizeof(addr
)) < 0)
62 error(-1, errno
, "connect");
64 send(sock
, &buffer
, sizeof(buffer
), 0);
65 if (read(sock
, &buffer
, sizeof(buffer
)) == -1)
66 error(-1, errno
, "waiting read");
68 gettimeofday(&end
, NULL
);
69 lat
= timediff(start
, end
);
75 if (getsockname(sock
, (struct sockaddr
*)&laddr
, &len
) == -1)
76 error(-1, errno
, "getsockname");
77 printf("port: %d, lat: %lu, avg: %lu, nr: %lu\n",
78 ntohs(laddr
.sin_port
), lat
,
79 sum_lat
/ nr_lat
, nr_lat
);
86 static void server(int sock
, struct sockaddr_in address
)
89 int addrlen
= sizeof(address
);
93 accepted
= accept(sock
, (struct sockaddr
*)&address
,
94 (socklen_t
*)&addrlen
);
96 error(-1, errno
, "accept");
98 if (read(accepted
, &buffer
, sizeof(buffer
)) == -1)
99 error(-1, errno
, "read");
104 static void sig_handler(int signum
)
106 kill(SIGTERM
, child_pid
);
110 int main(int argc
, char const *argv
[])
114 struct sockaddr_in address
;
115 struct sockaddr_in laddr
;
116 socklen_t len
= sizeof(laddr
);
118 if (signal(SIGTERM
, sig_handler
) == SIG_ERR
)
119 error(-1, errno
, "signal");
121 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
123 error(-1, errno
, "socket");
125 if (setsockopt(sock
, SOL_SOCKET
, SO_REUSEADDR
| SO_REUSEPORT
,
126 &opt
, sizeof(opt
)) == -1)
127 error(-1, errno
, "setsockopt");
129 address
.sin_family
= AF_INET
;
130 address
.sin_addr
.s_addr
= INADDR_ANY
;
131 /* dynamically allocate unused port */
132 address
.sin_port
= 0;
134 if (bind(sock
, (struct sockaddr
*)&address
, sizeof(address
)) < 0)
135 error(-1, errno
, "bind");
137 if (listen(sock
, 3) < 0)
138 error(-1, errno
, "listen");
140 if (getsockname(sock
, (struct sockaddr
*)&laddr
, &len
) == -1)
141 error(-1, errno
, "getsockname");
143 fprintf(stderr
, "server port: %d\n", ntohs(laddr
.sin_port
));
146 client(ntohs(laddr
.sin_port
));