// GO
ln, err := net.Listen("tcp", "0.0.0.0:8080")
if err != nil {
fmt.Println(err)
return
}
// C
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed\n");
return -1;
} else {
printf("socket successfully created\n");
}
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 ){
printf("setsockopt failed\n");
return -1;
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
if ((bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) != 0) {
printf("socket bind failed\n");
return -1;
}
if(make_socket_non_blocking(sockfd) < 0){
printf("non-blocking failed\n");
return -1;
}
if ((listen(sockfd, client_num + 1)) != 0) {
printf("listen failed\n");
return -1;
}
./setup.sh
make
#define MAXCLIENT 10000
#define CLIENTS_PER_THREAD 100
#define THREAD_ITER 100
#define MAXBUFFLEN 65536
#define PORT 9999
extern char mode;
extern char server_mode;
extern int client_num;
extern uint8_t** client_buff;
extern int wfds[MAXCLIENT];
extern uint8_t wbuff[MAXCLIENT / CLIENTS_PER_THREAD][MAXBUFFLEN];
extern atomic_uint_fast8_t wdones[MAXCLIENT / CLIENTS_PER_THREAD];
void* run_client_thread(void* varg);
int make_socket_non_blocking (int sfd);
int run_select(int fd, struct sockaddr_in* servaddr);
int run_poll(int fd, struct sockaddr_in* servaddr);
int run_epoll(int fd, struct sockaddr_in* servaddr);
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
max_fd = fd;
for(int i = 0; i < client_num; i++){
client_fd = client_fds[i];
if(client_fd > 0){
FD_SET(client_fd, &readfds);
}
if(client_fd > max_fd){
max_fd = client_fd;
}
}
event = select(max_fd + 1, &readfds, NULL, NULL, NULL);
...
for(int i = 0; i < client_num; i++){
if(event == 0){
break;
}
client_fd = client_fds[i];
if(client_fd == 0){
continue;
}
if(FD_ISSET(client_fd, &readfds)){
valread = 0;
n = 0;
event -= 1;
pollfds[0].fd = fd;
pollfds[0].events = POLLIN;
for(int i = 1; i < client_num + 1; i++){
pollfds[i].fd = 0;
pollfds[i].events = POLLIN;
}
while(keep){
event = poll(pollfds, client_num + 1, -1);
do {
if(pollfds[0].revents & POLLIN){
...
for(int i = 1; i < client_num + 1; i++){
idx = i - 1;
if(event == 0){
break;
}
if(pollfds[i].fd == 0){
continue;
}
if(pollfds[i].revents & POLLIN){
ev.data.fd = fd;
ev.events = EPOLLIN;
if(epoll_ctl(eplfd, EPOLL_CTL_ADD, fd, &ev) < 0){
printf("epoll add failed\n");
return -1;
}
while(keep){
event = epoll_wait(eplfd, evs, client_num + 1, -1);
for(int i = 0 ; i < event; i++){
if (
evs[i].events & EPOLLHUP ||
evs[i].events & EPOLLERR ||
(!(evs[i].events & EPOLLIN))
){
continue;
}
if(evs[i].data.fd == fd){
...
} else {
if(connections != MAXCLIENT){
continue;
} else {
if(connections_printed == 0){
printf("connection reached: %d\n", connections);
connections_printed = 1;
}
}
idx = epoll_get_idx(client_fds, evs[i].data.fd);
if(idx < 0){
printf("epoll get slot failed\n");
continue;
}
...
DESCRIPTION top
WARNING: select() can monitor only file descriptors numbers that
are less than FD_SETSIZE (1024)—an unreasonably low limit for many
modern applications—and this limitation will not change. All
modern applications should instead use poll(2) or epoll(7), which
do not suffer this limitation.
...
# https://man7.org/linux/man-pages/man2/select.2.html
#define MAXCLIENT 1000
make clean
make
ten-k$ sudo ip netns exec net1 ./tenk.out s s
socket successfully created
server mode: select
ten-k$ ./tenk.out c 192.168.62.6
creating connections: 1000
connectons : 0...
connectons : 100...
connectons : 200...
connectons : 300...
connectons : 400...
connectons : 500...
connectons : 600...
connectons : 700...
connectons : 800...
connectons : 900...
created connections: 1000
creating threads: 10
created threads: 10
running...
done
sec: 0 ms: 152
ten-k$ sudo ip netns exec net1 ./tenk.out s
p
socket successfully created
server mode: poll
ten-k$ ./tenk.out c 192.168.62.6
client mode: address: 192.168.62.6
creating connections: 1000
connectons : 0...
connectons : 100...
connectons : 200...
connectons : 300...
connectons : 400...
connectons : 500...
connectons : 600...
connectons : 700...
connectons : 800...
connectons : 900...
created connections: 1000
creating threads: 10
created threads: 10
running...
done
sec: 0 ms: 193
ten-k$ sudo ip netns exec net1 ./tenk.out s
e
socket successfully created
server mode: epoll
ten-k$ ./tenk.out c 192.168.62.6
client mode: address: 192.168.62.6
creating connections: 1000
connectons : 0...
connectons : 100...
connectons : 200...
connectons : 300...
connectons : 400...
connectons : 500...
connectons : 600...
connectons : 700...
connectons : 800...
connectons : 900...
created connections: 1000
creating threads: 10
created threads: 10
running...
done
sec: 0 ms: 125
#define MAXCLIENT 10000
make clean
make
sudo ip netns exec net1 /bin/bash
sudo -i
ten-k# ulimit -n
1024
ten-k# ulimit -n 10240
ten-k# ulimit -n
10240
ten-k# ./tenk.out s s
socket successfully created
server mode: select
*** bit out of range 0 - FD_SETSIZE on fd_set ***: terminated
Aborted (core dumped)
connection with the server failed: 5118
created connections: 10000
creating threads: 100
ten-k# ./tenk.out s p
socket successfully created
server mode: poll
ten-k# ./tenk.out c 192.168.62.6
client mode: address: 192.168.62.6
creating connections: 10000
connectons : 0...
connectons : 100...
connectons : 200...
connectons : 300...
connectons : 400.
...
connectons : 9500...
connectons : 9600...
connectons : 9700...
connectons : 9800...
connectons : 9900...
created connections: 10000
creating threads: 100
created threads: 100
running...
done
sec: 3 ms: 453
ten-k# ./tenk.out s e
socket successfully created
server mode: epoll
ten-k# ./tenk.out c 192.168.62.6
client mode: address: 192.168.62.6
creating connections: 10000
connectons : 0...
connectons : 100...
connectons : 200...
connectons : 300...
connectons : 400...
connectons : 500...
connectons : 600...
...
connectons : 9300...
connectons : 9400...
connectons : 9500...
connectons : 9600...
connectons : 9700...
connectons : 9800...
connectons : 9900...
created connections: 10000
creating threads: 100
created threads: 100
running...
done
sec: 0 ms: 139