seantywork

01


// 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;
        } 

02


./setup.sh

03


make


04




#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);

05


        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;

06


    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){


07



    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;
                }

08


...
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

09


#define MAXCLIENT 1000

10


make clean

make

11


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

12


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

13


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

14

#define MAXCLIENT 10000

15


make clean
make

16

sudo ip netns exec net1 /bin/bash



sudo -i

17

ten-k# ulimit -n
1024

ten-k# ulimit -n 10240


ten-k# ulimit -n
10240

18

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

19


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

20

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