一次select多个socket的测试结果

接收端程序: 1024个socket建立连接后,创建8个线程收数据,每个线程处理128个socket, 每个线程先select这128个socket,然后用FD_ISSET对这128个socket进行检查和读出。

用脚本bw.sh 统计得到的接收端的总带宽为 0.114 Gb/s, 用 iftop 查看得到的接收端带宽在前几秒为3Gb/s, 然后下降到 112 Mb/s。

接收队列的长度为3.7MB。由此可见接收端很慢。

这种一次select多个socket的工作方式效率很低, 不应该采用。

发送端程序:server1bak.c 布置4个发送端

 1 #include <stdio.h>
  2 #include <stdlib.h>
  3
  4 #include<pthread.h>
  5 #include <unistd.h>
  6
  7 #include <sys/socket.h>
  8 #include <arpa/inet.h>
  9 #include <netinet/in.h>
 10 #include <netinet/tcp.h>
 11 #include<sys/time.h>
 12 #include<errno.h>
 13 #include<string.h>
 14
 15 #define IP "192.168.250.147"
 16 #define PORT  33333
 17 #define SOCKNUM  256
 18 #define PACKETSIZE 2048
 19
 20 typedef struct {
 21     int sock;
 22 }ARG;
 23
 24 pthread_t tid[SOCKNUM];
 25
 26
 27 int SetSocketOptions(int fd)
 28 {
 29     int sockopt = 0;
 30     int SOCKET_ERROR = -1;
 31     static const int c_so_rcvbuf = 256*1024;
32     static const int c_so_sndbuf = 256*1024;
 33
 34     sockopt = 1;
 35     if ( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&sockopt, sizeof(sockopt)) == SOCKET_ERROR )
 36     {
 37         perror("set reuseaddr error");
 38         return -1;
 39     }
 40
 41     sockopt = c_so_sndbuf;
 42     if ( setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char*)&sockopt, sizeof(sockopt)) == SOCKET_ERROR )
 43     {
 44         perror("set so_sndbuf error");
 45         return -1;
 46     }
 47
 48     sockopt = c_so_rcvbuf;
 49     if ( setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char*)&sockopt, sizeof(sockopt)) == SOCKET_ERROR )
 50     {
 51         perror("set so_rcvbuf error");
 52         return -1;
 53     }
 54 }
 55
 56
 57
 58
 59 int senddata(int sock)
 60 {
61     int ret;
 62     char temp[PACKETSIZE+1] = "I want to know!";
 63     int size_left=2048;
 64     while( size_left > 0)
 65     {
 66         ret = send(sock, temp, size_left, 0);
 67         if (ret < 0)
 68         {
 69             perror("send fail");
 70             exit(1);
 71         }
 72         size_left -= ret;
 73     }
 74
 75     return size_left;
 76 }
 77
 78
 79 int read_cwnd(int tcp_work_socket)
 80 {
 81     struct tcp_info info;
 82     socklen_t  tcp_info_length = sizeof(tcp_info);
 83     if ( getsockopt(tcp_work_socket, SOL_TCP, TCP_INFO, (void *)&info, &tcp_info_length) == 0 ) {
 84         printf(" cwnd:%u, snd_ssthresh:%u, rtt:%u, rtt_d:%u\n",
 85                 info.tcpi_snd_cwnd,
 86                 info.tcpi_snd_ssthresh,
 87                 info.tcpi_rtt,
 88                 info.tcpi_rttvar
 89            );
90     }
 91     return 0;
 92 }
 93
 94
 95 void *sendData(void *arg)
 96 {
 97 #if 1
 98     ARG *a = (ARG *)arg;
 99     int accept_sock = a->sock;
100
101     long count = 0;
102     struct  timeval  start;
103     struct  timeval  end;
104     unsigned long timer=0;
105     gettimeofday(&start,NULL);
106
107
108     while(1){
109         senddata(accept_sock);
110         usleep(900);
111         if(pthread_self()== tid[0])
112         {
113 //      FILE* fpointer = fopen("result.out", "a+");
114         count++;
115         gettimeofday(&end,NULL);
116         timer = 1000000 * (end.tv_sec-start.tv_sec)+ end.tv_usec-start.tv_usec;
117         if(timer%2000== 0)
118         {
119             printf("count: %ld, socket: %ld,  %lf s, %lf Gb/s, ", count, accept_sock,  timer/1000000.0, count*2048.0/timer/1024*8);
120             read_cwnd(accept_sock);
121         }
122
123 #if 1
124         if(timer > 3600000000)
125         {
126             printf("before close: timer: %ld\n", timer);
127             close(accept_sock);
128 //          fclose(fpointer);
129             break;
130         }
131 #endif
132         }
133     }
134     return 0;
135 #endif
136
137 }
138
139
140
141 int main()
142 {
143     int accept_sock[SOCKNUM];
144     struct sockaddr_in addr_ser;
145
146
147     int sock = socket(AF_INET, SOCK_STREAM, 0);
148     if (sock < 0)
149     {
150         perror("create sock fail");
151         exit(1);
152     }
153
154     addr_ser.sin_family = AF_INET;
155     addr_ser.sin_port = htons(PORT);
156 //  addr_ser.sin_addr.s_addr = inet_addr(IP);
157     addr_ser.sin_addr.s_addr = htonl(INADDR_ANY);
158
159
160     int sockopt = 1;
161     if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *)&sockopt, sizeof(int)) < 0)
162     {
163         perror("setsockopt fail");
164         exit(1);
165     }
166
167     if (bind(sock, (struct sockaddr*)&addr_ser, sizeof(struct sockaddr)) < 0)
168     {
169         perror("bind fail");
170         exit(1);
171     }
172
173
174 #if 0
175     if ( SetSocketOptions(sock) == -1)
176     {
177         perror("set socket options error");
178         exit(1);
179     }
180 #endif
181
182     if (listen(sock, 2000) < 0)
183     {
184         perror("listen fail");
185         exit(1);
186     }
187
188
189    for(int i=0; i<SOCKNUM; i++)
190    {
191
192     accept_sock[i] = accept(sock, 0, 0);
193     if (accept_sock[i] < 0)
194     {
195         perror("accept fail");
196         exit(1);
197     }
198     printf("accept ok!\n");
199    }
200
201
202 #if 1
203
204    //static extern  pthread_t tid[SOCKNUM];
205    ARG a[SOCKNUM];
206    for(int i=0; i<SOCKNUM; i++){
207    a[i].sock = accept_sock[i];
208    pthread_create(&tid[i], 0, sendData, (void *)&a[i]);
209    }
210 #endif
211
212 #if 1
213    for(int i=0; i<SOCKNUM; i++)
214    {
215        pthread_join(tid[i], 0);
216    }
217 #endif
218
219    return 0;
220 }

接收端代码:client1_multi_select2.c

1 #include <stdio.h>
  2 #include <stdlib.h>
  3
  4 #include<pthread.h>
  5 #include <unistd.h>
  6 #include <time.h>
  7
  8 #include<sys/ioctl.h>
  9 #include <sys/socket.h>
 10 #include <arpa/inet.h>
 11 #include <netinet/in.h>
 12 #include<sys/time.h>
 13 #include<string>
 14
 15 #define PORT 33333
 16
 17 #define SOCKNUM 1024
 18 #define THREAD_NUM 8
 19 #define SOCKET_PER_THREAD 128
 20 #define SERVER_NUM 4
 21 #define MSGSIZE 2048
 22
 23 typedef struct{
 24     int sock[SOCKET_PER_THREAD];
 25 }ARG;
 26
 27 int SetSocketOptions(int fd)
 28 {
 29     int sockopt = 0;
 30     int SOCKET_ERROR = -1;
 31     static const int c_so_rcvbuf = 256*1024;
32     static const int c_so_sndbuf = 256*1024;
 33
 34     sockopt = 1;
 35     if ( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&sockopt, sizeof(sockopt)) == SOCKET_ERROR )
 36     {
 37         perror("set reuseaddr error");
 38         return -1;
 39     }
 40
 41     sockopt = c_so_sndbuf;
 42     if ( setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char*)&sockopt, sizeof(sockopt)) == SOCKET_ERROR )
 43     {
 44         perror("set so_sndbuf error");
 45         return -1;
 46     }
 47
 48     sockopt = c_so_rcvbuf;
 49     if ( setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char*)&sockopt, sizeof(sockopt)) == SOCKET_ERROR )
 50     {
 51         perror("set so_rcvbuf error");
 52         return -1;
 53     }
 54 }
 55
 56 int recvdata(int sock, char *buffer)
 57 {
 58     int msgsize = MSGSIZE;
 59     int ret;
 60     int nrecv=0;
61     while (nrecv < msgsize)
 62     {
 63         ret = recv(sock, buffer, msgsize-nrecv, 0);
 64         if (ret < 0)
 65         {
 66             perror("recv fail");
 67             exit(1);
 68         }
 69         else
 70         {
 71             nrecv += ret;
 72         }
 73     }
 74     return nrecv;
 75 }
 76
 77 int max(int a, int b)
 78 {
 79     if(a >= b)
 80         return a;
 81     else
 82         return b;
 83 }
 84
 85
 86
 87
 88 int  poll_and_recv(fd_set recv_fds, int maxfd, int* socket)
89 {
 90 #if 1
 91     char buffer[MSGSIZE] = "0";
 92     struct timeval c_select_timeout = {0, 0};
 93     int sel = select(maxfd+1, &recv_fds, NULL, NULL, &c_select_timeout);
 94     if(sel == 0)
 95     {
 96         return 0;
 97     }
 98     else if(sel > 0)
 99     {
100         for(int i=0; i<SOCKET_PER_THREAD; i++)
101         {
102             if( FD_ISSET(socket[i], &recv_fds) ) // socket is readable
103             {
104                 int length;
105                 int status = ioctl(socket[i], FIONREAD, &length);
106                 if(status == -1)
107                 {
108                     printf("Error reading input size\n");
109                 }
110                 if(length)
111                 {
112                     //printf("data in socket %d : %d\n", socket[i], length);
113 //                  for(int num=0; num<300; num++)
114 //                  {
115                         recvdata(socket[i], buffer);
116 //                  }
117                 }
118                 else // length==0
119                 {
120                     printf("Nothing to read, eof??\n");
121                     if(socket[i] != -1)
122                     {
123                         close(socket[i]);
124                         socket[i] = -1;
125                     }
126                     perror("socket flagged but no data available probable EOF");
127                 }
128
129             } // FD_ISSET != 0
130         } // i < SOCKET_PER_THREAD
131     } // sel > 0
132     else // sel < 0
133     {
134         for (int i=0; i<SOCKET_PER_THREAD; i++)
135         {
136             if(socket[i] != -1)
137             {
138                 close(socket[i]);
139                 socket[i] = -1;
140             }
141         }
142         perror("select<0 error");
143         return 0;
144     }
145 146 #endif
147     return 1;
148
149 }
150
151
152
153 void *recvData(void *arg)
154 {
155     ARG* a = (ARG*)arg;
156     int *socket = a->sock;
157     char buffer[MSGSIZE] = "0";
158     int count = 0;
159
160     int maxfd = 0;
161     for(int i=0; i<SOCKET_PER_THREAD; i++)
162     {
163         maxfd = max(socket[i], maxfd);
164     }
165
166     while(1)
167     {
168         fd_set recv_fds;
169         for(int i=0; i<SOCKET_PER_THREAD; i++)
170         {
171             FD_ZERO(&recv_fds);
172             FD_SET(socket[i], &recv_fds);
173         }
174         poll_and_recv(recv_fds, maxfd, socket);
175     }
176     return 0;
177 }
178
179
180 int main()
181 {
182     int sock[SERVER_NUM][SOCKNUM/SERVER_NUM];
183     struct sockaddr_in addr_ser[SERVER_NUM];
184     struct sockaddr_in addr_cli[SERVER_NUM][SOCKNUM/SERVER_NUM];
185
186     std::string local_ip("192.168.250.141");
187
188     std::string server_ip[SERVER_NUM] = {"192.168.250.146", "192.168.250.147", "192.168.250.142", "192.168.250.143"};
189     //std::string server_ip[SERVER_NUM] = {"192.168.251.166", "192.168.251.167", "192.168.251.162", "192.168.251.163"};
190 //  std::string server_ip[SERVER_NUM] = {"192.168.251.163"};
191     for(int ser=0; ser < SERVER_NUM; ser++)
192     {
193     for(int i=0; i<SOCKNUM/SERVER_NUM; i++)
194     {
195         sock[ser][i] = socket(AF_INET, SOCK_STREAM, 0);
196         if(sock[ser][i] < 0)
197         {
198             printf("%d ", i);
199             perror("create socket fail");
200         }
201
202         addr_ser[ser].sin_family = AF_INET;
203         addr_ser[ser].sin_port = htons(PORT);
204         addr_ser[ser].sin_addr.s_addr = inet_addr(server_ip[ser].c_str());
205
206         addr_cli[ser][i].sin_family = AF_INET;
207         addr_cli[ser][i].sin_port = 0;
208         addr_cli[ser][i].sin_addr.s_addr = inet_addr(local_ip.c_str());
209
210
211         int sockopt = 1;
212         if ( setsockopt(sock[ser][i], SOL_SOCKET, SO_REUSEADDR, (char*)&sockopt, sizeof(sockopt)) == -1 )
213         {
214             perror("set reuseaddr error");
215             exit(1);
216         }
217
218
219 #if 0
220
221         if ( SetSocketOptions(sock[ser][i]) == -1)
222         {
223             perror("set socket options error");
224             exit(1);
225         }
226 #endif
227
228         if( bind(sock[ser][i], (struct sockaddr*)&addr_cli[ser][i], sizeof(addr_cli[ser][i]) ) < 0 )
229         {
230             perror("TCP bind: ");
231             exit(1);
232         }
233         printf("bind ok!\n");
234
235         if(connect(sock[ser][i], (struct sockaddr*)&addr_ser[ser], sizeof(struct sockaddr)) < 0)
236         {
237             perror("connect fail:");
238             exit(1);
239         }
240         printf("connect ok!\n");
241
242     }
243
244     }
245
246
247     int socket[SOCKNUM] ;
248     int count=0;
249     for(int i=0; i< SERVER_NUM; i++)
250     {
251         for(int j=0; j<SOCKNUM/SERVER_NUM; j++)
252         {
253             socket[count++] = sock[i][j];
254         }
255     }
256
257     pthread_t tid[THREAD_NUM];
258     ARG a[THREAD_NUM];
259     for(int i=0; i<THREAD_NUM; i++)
260     {
261         for(int j=0; j<SOCKET_PER_THREAD; j++)
262         {
263         a[i].sock[j] = socket[i*SOCKET_PER_THREAD+j];
264         }
265         pthread_create(&tid[i], 0, recvData, (void *)&a[i]);
266     }
267
268     for(int i=0; i<SOCKNUM; i++)
269     {
270         pthread_join(tid[i], 0);
271     }
272
273     return 0;
274 }

计算带宽代码:bw.sh

1 #!/bin/bash
2
3
4 bw1=`ifconfig eth4 |grep "RX bytes"|awk ‘{print $2}‘|awk -F : ‘{print $2}‘`
5 sleep 60
6 bw2=`ifconfig eth4 |grep "RX bytes"|awk ‘{print $2}‘|awk -F : ‘{print $2}‘`
7
8 echo "($bw2-$bw1)/1024.0/1024.0/1024.0*8/60.0"|bc -l
时间: 2024-10-19 01:59:27

一次select多个socket的测试结果的相关文章

用select模拟一个socket server

1, 必须在非阻塞模式下,才能实现IO的多路复用,否则一个卡住就都卡住了. 先检测自己,现在没有客户端连进来,所以会卡住. # 用select去模拟socket,实现单线程下的多路复用 import select import socket import queue server = socket.socket() server.bind(('localhost', 9000)) server.listen(1024) server.setblocking(False) # 设置为不阻塞,acc

loadrunner简单使用——HTTP,WebService,Socket压力测试脚本编写

先说明一下,本人是开发,对测试不是特别熟悉,但因工作的需要,也做过一些性能测试方面的东西.比较久之前很简单的用过,最近又用到了,熟悉一下.现做一个总结. 使用loadrunner进行压力测试主要分两步,第一步是编写脚本(比较重点),第二步执行测试(配置都是在界面上点点就行了,当然我只的是比较简单的,能满足日常需要的),第三步分析结果(这一步比较高深,但是对于我来说能看懂简单的性能指标就OK了).所以这里就说一下脚本的编写,给未来再用到做参考. 1.HTTP的GET请求 这里以访问百度为例,地址h

Android Socket简单测试

这里是将pc作为server,设备作为客户端. Server端代码: public static final String SERVERIP = "192.168.0.2"; public static final int SERVERPORT = 51706; public void run() { try { System.out.println("S: Connecting..."); ServerSocket serverSocket = new Serve

C#下用select方法实现socket服务端

select是一种比较古老但一直被证明性能很好的socket模式,它可以让你以消息驱动的模式书写socket程序.网上C++的例子很多,但C#的例子极少. 上代码: namespace Server { class Program { // Thread signal. public static ManualResetEvent allDone = new ManualResetEvent(false); private static Socket handler = null; privat

c socket 开发测试

c语言异常 参照他人代码写一个tcp的 socket 开发测试 异常A,在mac osx系统下编译失败,缺库转到debian下. 异常B,include引用文件顺序不对,编译大遍异常 异常C,/usr/include/x86_64-linux-gnu/sys/types.h:34:1: error: unknown type name ‘__u_char’ 文件前注释的问题,删掉注释则通过 #include <sys/types.h> #include <sys/socket.h>

linux socket can测试

1. Overview / What is Socket CAN -------------------------------- The socketcan package is an implementation of CAN protocols (Controller Area Network) for Linux.  CAN is a networking technology which has widespread use in automation, embedded device

loadrunner简单使用&mdash;&mdash;HTTP,WebService,Socket压力测试脚本编写

先说明一下,本人是开发,对测试不是特别熟悉,但因工作的需要,也做过一些性能测试方面的东西.比较久之前很简单的用过,最近又用到了,熟悉一下.现做一个总结. 使用loadrunner进行压力测试主要分两步:第一步是编写脚本(比较重点),第二步执行测试(配置都是在界面上点点就行,当然我只是比较简单的,能满足日常需要的),第三步分析结果(这一步比较高深,但是对于我来说能看懂简单的性能指标就OK)所以这里就说一下脚本的编写,给未来再用到做参考. 1,HTTP的GET请求 这里以访问百度为例,地址http:

(转载)loadrunner简单使用——HTTP,WebService,Socket压力测试脚本编写

原文出处:http://ajita.iteye.com/blog/1728243/ 先说明一下,本人是开发,对测试不是特别熟悉,但因工作的需要,也做过一些性能测试方面的东西.比较久之前很简单的用过,最近又用到了,熟悉一下.现做一个总结. 使用loadrunner进行压力测试主要分两步,第一步是编写脚本(比较重点),第二步执行测试(配置都是在界面上点点就行了,当然我只的是比较简单的,能满足日常需要的),第三步分析结果(这一步比较高深,但是对于我来说能看懂简单的性能指标就OK了).所以这里就说一下脚

.Net Core Socket 压力测试

想起之前同事说go lang写的push service单机可以到达80万连接,于是就想测试下.Net Core能达到多少.简单地写了全异步的服务端和客户端代码(未作任何优化).测试环境只是笔记本18万连接CPU点26%左右内存点1.2G,目测放到服务器上80万还是有希望. 一.测试代码 服务端:启动TcpListener监听,异步接受客户端连接AcceptTcpClientAsync.连接到达后异步读取客户端数据,收到数据后原封不动发送到客户端.客户端:启动60个任务,每个任务依次异步连接到服