Server listening on 5001 (test #2)
-----------------------------------------------------------
+```
+
+
+#
+
+```shell
+
+192.168.62.5 -> 192.168.62.6
+41440 -> 9999
+
+0000 68 68 77 68 72 33 66 73 68 36 33 70 36 7a 65 63 hhwhr3fsh63p6zec
+0010 74 76 79 71 6c 6f 66 36 6b 77 6e 6f 6c 36 70 6f tvyqlof6kwnol6po
+0020 6e 7a 75 70 00 nzup.
+
+
+
+```
+
+#
+
+```shell
+192.168.62.6 -> 192.168.62.5
+9999 -> 41440
+
+ TCP payload (1 byte)
+Data (1 byte)
+
+0000 09 .
+ Data: 09
+ [Length: 1]
+
+
+```
+
+#
+
+```shell
+
+192.168.62.5 -> 192.168.62.6
+41440 -> 9999
+
+Data (4 bytes)
+
+0000 00 00 00 7c ...|
+ Data: 0000007c
+ [Length: 4]
+
+
+
+```
+
+```shell
+
+192.168.62.5 -> 192.168.62.6
+41440 -> 9999
+
+ TCP payload (124 bytes)
+Data (124 bytes)
+
+0000 7b 22 74 63 70 22 3a 74 72 75 65 2c 22 6f 6d 69 {"tcp":true,"omi
+0010 74 22 3a 30 2c 22 74 69 6d 65 22 3a 31 30 2c 22 t":0,"time":10,"
+0020 6e 75 6d 22 3a 30 2c 22 62 6c 6f 63 6b 63 6f 75 num":0,"blockcou
+0030 6e 74 22 3a 30 2c 22 70 61 72 61 6c 6c 65 6c 22 nt":0,"parallel"
+0040 3a 31 2c 22 6c 65 6e 22 3a 31 33 31 30 37 32 2c :1,"len":131072,
+0050 22 70 61 63 69 6e 67 5f 74 69 6d 65 72 22 3a 31 "pacing_timer":1
+0060 30 30 30 2c 22 63 6c 69 65 6e 74 5f 76 65 72 73 000,"client_vers
+0070 69 6f 6e 22 3a 22 33 2e 31 36 22 7d ion":"3.16"}
+
+
+
+```
+
+#
+
+```shell
+
+192.168.62.6 -> 192.168.62.5
+9999 -> 41440
+
+ TCP payload (1 byte)
+Data (1 byte)
+
+0000 0a .
+ Data: 0a
+ [Length: 1]
+
+```
+
+#
+
+```shell
+
+
+192.168.62.5 -> 192.168.62.6
+41448 -> 9999
+
+ TCP payload (37 bytes)
+Data (37 bytes)
+
+0000 68 68 77 68 72 33 66 73 68 36 33 70 36 7a 65 63 hhwhr3fsh63p6zec
+0010 74 76 79 71 6c 6f 66 36 6b 77 6e 6f 6c 36 70 6f tvyqlof6kwnol6po
+0020 6e 7a 75 70 00 nzup.
+
+```
+
+#
+
+```shell
+
+192.168.62.6 -> 192.168.62.5
+9999 -> 41440
+
+ TCP payload (1 byte)
+Data (1 byte)
+
+0000 01 .
+ Data: 01
+ [Length: 1]
+```
+
+```shell
+
+192.168.62.6 -> 192.168.62.5
+9999 -> 41440
+
+
+ TCP payload (1 byte)
+Data (1 byte)
+
+0000 02 .
+ Data: 02
+ [Length: 1]
+
+
+```
+
+#
+
+```shell
+
+192.168.62.5 -> 192.168.62.6
+41448 -> 9999
+
+ TCP payload (7240 bytes)
+Data (7240 bytes)
+
+0000 55 7c 4c 02 5e 17 5c bc 5b da b6 c0 6f 5d f6 d7 U|L.^.\.[...o]..
+0010 c5 df 58 8d e3 e1 5c cc a8 26 ce c0 77 08 e7 8b ..X...\..&..w...
+0020 c3 bc 5d 60 bc 19 6b 6b 94 f1 f3 e8 ae f3 fd b4 ..]`..kk........
+0030 2b b9 2f ca 77 2b 43 15 62 56 eb 13 ff b0 c7 82 +./.w+C.bV......
+0040 b9 6e 78 a1 3c 2d 90 6e b8 48 73 f8 8e d8 5c 20 .nx.<-.n.Hs...\
+
+```
+
+#
+
+```c
+
+static uint8_t hello_ctl[37] = {0};
+static uint8_t answer_hello_ctl[1] = {0x09};
+static uint8_t info_size[4] = {0};
+static uint8_t* info = NULL;
+static uint8_t answer_info[1] = {0x0a};
+static uint8_t hello[37] = {0};
+static uint8_t answer_hello_1[1] = {0x01};
+static uint8_t answer_hello_2[1] = {0x02};
+
+```
+
+#
+
+```shell
+
+Frame 55388: 70 bytes on wire (560 bits), 70 bytes captured (560 bits) on interface veth11, id 0
+Ethernet II, Src: 82:c8:ff:58:e7:e7 (82:c8:ff:58:e7:e7), Dst: 46:5f:bb:78:a9:5e (46:5f:bb:78:a9:5e)
+Internet Protocol Version 4, Src: 192.168.62.5, Dst: 192.168.62.6
+Transmission Control Protocol, Src Port: 33886, Dst Port: 9999, Seq: 166, Ack: 6, Len: 4
+Data (4 bytes)
+ Data: 00000145
+ [Length: 4]
+
+
+```
+
+```shell
+
+0000 46 5f bb 78 a9 5e 82 c8 ff 58 e7 e7 08 00 45 00 F_.x.^...X....E.
+0010 01 79 14 2c 40 00 40 06 27 f7 c0 a8 3e 05 c0 a8 .y.,@.@.'...>...
+0020 3e 06 84 5e 27 0f 99 98 11 ab 94 a1 6d 1f 80 18 >..^'.......m...
+0030 01 f6 fe c7 00 00 01 01 08 0a 9d eb 12 cb f2 7d ...............}
+0040 0e eb 7b 22 63 70 75 5f 75 74 69 6c 5f 74 6f 74 ..{"cpu_util_tot
+0050 61 6c 22 3a 39 39 2e 38 39 31 31 32 35 35 39 32 al":99.891125592
+0060 33 34 36 33 37 2c 22 63 70 75 5f 75 74 69 6c 5f 34637,"cpu_util_
+0070 75 73 65 72 22 3a 31 2e 31 39 33 33 34 33 30 35 user":1.19334305
+0080 30 38 32 39 39 33 31 32 2c 22 63 70 75 5f 75 74 08299312,"cpu_ut
+0090 69 6c 5f 73 79 73 74 65 6d 22 3a 39 38 2e 36 39 il_system":98.69
+00a0 37 37 38 32 35 34 31 35 31 36 34 34 36 2c 22 73 7782541516446,"s
+00b0 65 6e 64 65 72 5f 68 61 73 5f 72 65 74 72 61 6e ender_has_retran
+00c0 73 6d 69 74 73 22 3a 31 2c 22 63 6f 6e 67 65 73 smits":1,"conges
+00d0 74 69 6f 6e 5f 75 73 65 64 22 3a 22 63 75 62 69 tion_used":"cubi
+00e0 63 22 2c 22 73 74 72 65 61 6d 73 22 3a 5b 7b 22 c","streams":[{"
+00f0 69 64 22 3a 31 2c 22 62 79 74 65 73 22 3a 37 36 id":1,"bytes":76
+0100 39 38 39 30 37 31 33 36 2c 22 72 65 74 72 61 6e 98907136,"retran
+0110 73 6d 69 74 73 22 3a 30 2c 22 6a 69 74 74 65 72 smits":0,"jitter
+0120 22 3a 30 2c 22 65 72 72 6f 72 73 22 3a 30 2c 22 ":0,"errors":0,"
+0130 6f 6d 69 74 74 65 64 5f 65 72 72 6f 72 73 22 3a omitted_errors":
+0140 30 2c 22 70 61 63 6b 65 74 73 22 3a 30 2c 22 6f 0,"packets":0,"o
+0150 6d 69 74 74 65 64 5f 70 61 63 6b 65 74 73 22 3a mitted_packets":
+0160 30 2c 22 73 74 61 72 74 5f 74 69 6d 65 22 3a 30 0,"start_time":0
+0170 2c 22 65 6e 64 5f 74 69 6d 65 22 3a 31 2e 30 30 ,"end_time":1.00
+0180 35 31 33 33 7d 5d 7d 5133}]}
+
+
```
\ No newline at end of file
-GCC_FLAGS := -Wall -O2
+GCC_FLAGS := -Wall -O2 -g
all: iperf_s.o
- gcc $(GCC_FLAGS) -I. -o iperf_s.out main.c iperf_s.o
+ gcc $(GCC_FLAGS) -I. -o iperf_s.out main.c iperf_s.o -lpthread
iperf_s.o:
#include "iperf_s.h"
-int run_select(){
+static uint8_t ctl_hello[37] = {0};
+static uint8_t ctl_hellow_answer[1] = {0x09};
+static uint8_t ctl_info_size[4] = {0};
+static uint8_t* ctl_info = NULL;
+static uint8_t ctl_info_answer[1] = {0x0a};
+static uint8_t ctl_start_1[1] = {0x01};
+static uint8_t ctl_start_2[1] = {0x02};
+static uint8_t hello[37] = {0};
+int make_socket_non_blocking(int sfd){
+ int flags, s;
+
+ flags = fcntl (sfd, F_GETFL, 0);
+ if (flags == -1){
+ printf("fcntl get");
+ return -1;
+ }
+
+ flags |= O_NONBLOCK;
+ s = fcntl (sfd, F_SETFL, flags);
+ if (s == -1){
+ printf("fcntl set");
+ return -2;
+ }
+ return 0;
+}
+
+void* ctl_runner(void* varg){
+
+ int ctl_fd = *(int*)varg;
+
+ uint8_t end[1] = {0x0d};
+
+ sleep(3);
+ write(ctl_fd, end, 1);
+ read(ctl_fd, ctl_info_size, 4);
+ printf("%02x%02x%02x%02x\n", ctl_info_size[0], ctl_info_size[1], ctl_info_size[2], ctl_info_size[3]);
+ uint32_t isize = 276;
+ printf("size: %zu\n", isize);
+ ctl_info = (uint8_t*)malloc(isize * sizeof(uint8_t));
+ read(ctl_fd, ctl_info, isize);
+ printf("%s\n",ctl_info);
+ free(ctl_info);
+ close(ctl_fd);
+
+
+}
+
+int run_select(int fd, struct sockaddr_in* servaddr){
+
+ pthread_t tid;
+
+ int ctl_fd = 0;
+ int max_fd = 0;
+ int event = 0;
+ fd_set readfds;
+ int servlen;
+ int client_fds[MAXCLIENT] = {0};
+ int valread;
+ int n;
+ int client_fd;
+
+
+
+ servlen = sizeof(*servaddr);
+
+ while(1){
+
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+ max_fd = fd;
+
+ for(int i = 0; i < MAXCLIENT; 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);
+
+ if ((event < 0 ) && (errno != EINTR)){
+ printf("select error\n");
+ break;
+ }
+
+ do {
+ if(FD_ISSET(fd, &readfds)){
+ int added = 0;
+ int client_fd = accept(fd, (struct sockaddr*)servaddr, (socklen_t*)&servlen);
+ if(ctl_fd == 0){
+
+ ctl_fd = client_fd;
+
+ read(ctl_fd, ctl_hello, 37);
+ write(ctl_fd, ctl_hellow_answer, 1);
+ read(ctl_fd, ctl_info_size, 4);
+
+ uint32_t isize = ntohl(ctl_info_size);
+ ctl_info = (uint8_t*)malloc(isize * sizeof(uint8_t));
+ read(ctl_fd, ctl_info, isize);
+ write(ctl_fd, ctl_info_answer, 1);
+
+ pthread_create(&tid, NULL, ctl_runner, (void*)&ctl_fd);
+
+ free(ctl_info);
+
+ break;
+
+ } else {
+
+ read(client_fd, hello, 37);
+ write(ctl_fd, ctl_start_1, 1);
+ write(ctl_fd, ctl_start_2, 1);
+
+ }
+ if(client_fd < 0){
+ printf("failed to accept\n");
+ break;
+ }
+ if(make_socket_non_blocking(client_fd) < 0){
+ printf("accept non-blocking failed\n");
+ break;
+ }
+ for(int i = 0; i < MAXCLIENT; i++){
+ if(client_fds[i] == 0){
+ client_fds[i] = client_fd;
+ added = 1;
+ break;
+ }
+ }
+ if(added != 1){
+ printf("accept slot full\n");
+ break;
+ }
+
+ }
+ } while(0);
+
+ for(int i = 0; i < MAXCLIENT; 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;
+ while(valread < MAXBUFFLEN){
+ n = read(client_fd, client_buff[i] + valread, MAXBUFFLEN - valread);
+ if(n <= 0 && errno != EAGAIN){
+ client_fds[i] = 0;
+ break;
+ } else {
+ continue;
+ }
+ valread += n;
+ }
+
+ }
+ event -= 1;
+ }
+
+ }
return 0;
}
-int run_poll(){
+int run_poll(int fd, struct sockaddr_in* servaddr){
}
-int run_epoll(){
+int run_epoll(int fd, struct sockaddr_in* servaddr){
return 0;
#include <sys/time.h>
#include <fcntl.h>
#include <poll.h>
+#include <errno.h>
#define MAXCLIENT 32
#define MAXBUFFLEN 65536
extern char mode;
-extern int port;
+extern unsigned short port;
extern int client_num;
extern uint8_t client_buff[MAXCLIENT][MAXBUFFLEN];
+int make_socket_non_blocking (int sfd);
-int run_select();
+void* ctl_runner(void* varg);
-int run_poll();
+int run_select(int fd, struct sockaddr_in* servaddr);
-int run_epoll();
+int run_poll(int fd, struct sockaddr_in* servaddr);
+
+int run_epoll(int fd, struct sockaddr_in* servaddr);
char mode = 's';
-int port = 5001;
+unsigned short port = 5001;
int client_num = 1;
uint8_t client_buff[MAXCLIENT][MAXBUFFLEN];
int result = -1;
+ int sockfd;
+ int opt = 1;
+ struct sockaddr_in servaddr;
if(argc != 4){
printf("invalid mode: %s\n", argv[1]);
help();
- return -2;
+ return -1;
}
- sscanf(argv[2], "%d", &port);
+ sscanf(argv[2], "%hd", &port);
- printf("port to use: %d\n", port);
+ printf("port to use: %hd\n", port);
sscanf(argv[3], "%d", &client_num);
printf("client num: %d\n", client_num);
+ if(client_num > MAXCLIENT){
+
+ printf("too many clients: %d\n", client_num);
+
+ return -1;
+ }
+
+ 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;
+ }
if(mode == 's'){
- result = run_select();
+ result = run_select(sockfd, &servaddr);
} else if (mode == 'p') {
- result = run_poll();
+ result = run_poll(sockfd, &servaddr);
} else if (mode == 'e') {
- result = run_epoll();
+ result = run_epoll(sockfd, &servaddr);
}
- return 0;
+ return result;
}
\ No newline at end of file