OLD | NEW |
| (Empty) |
1 /* | |
2 This is a UDT self-testing program. | |
3 The code in the program may not be cleaned up yet. | |
4 | |
5 for performance testing, use appserver/appclient and sendfile/recvfile. | |
6 */ | |
7 | |
8 | |
9 #ifndef WIN32 | |
10 #include <unistd.h> | |
11 #include <cstdlib> | |
12 #include <cstring> | |
13 #include <netdb.h> | |
14 #include <signal.h> | |
15 #else | |
16 #include <winsock2.h> | |
17 #include <ws2tcpip.h> | |
18 #include <wspiapi.h> | |
19 #endif | |
20 #include <iostream> | |
21 #include <algorithm> | |
22 #include <udt.h> | |
23 | |
24 using namespace std; | |
25 | |
26 int g_IP_Version = AF_INET; | |
27 int g_Socket_Type = SOCK_STREAM; | |
28 | |
29 | |
30 int createUDTSocket(UDTSOCKET& usock, int version = AF_INET, int type = SOCK_STR
EAM, int port = 0, bool rendezvous = false) | |
31 { | |
32 addrinfo hints; | |
33 addrinfo* res; | |
34 | |
35 memset(&hints, 0, sizeof(struct addrinfo)); | |
36 | |
37 hints.ai_flags = AI_PASSIVE; | |
38 hints.ai_family = version; | |
39 hints.ai_socktype = type; | |
40 | |
41 char service[16]; | |
42 sprintf(service, "%d", port); | |
43 | |
44 if (0 != getaddrinfo(NULL, service, &hints, &res)) | |
45 { | |
46 cout << "illegal port number or port is busy.\n" << endl; | |
47 return -1; | |
48 } | |
49 | |
50 usock = UDT::socket(res->ai_family, res->ai_socktype, res->ai_protocol); | |
51 | |
52 int snd_buf = 64000; | |
53 int rcv_buf = 100000; | |
54 UDT::setsockopt(usock, 0, UDT_SNDBUF, &snd_buf, sizeof(int)); | |
55 UDT::setsockopt(usock, 0, UDT_RCVBUF, &rcv_buf, sizeof(int)); | |
56 snd_buf = 64000; | |
57 rcv_buf = 100000; | |
58 UDT::setsockopt(usock, 0, UDP_SNDBUF, &snd_buf, sizeof(int)); | |
59 UDT::setsockopt(usock, 0, UDP_RCVBUF, &rcv_buf, sizeof(int)); | |
60 int fc = 256; | |
61 UDT::setsockopt(usock, 0, UDT_FC, &fc, sizeof(int)); | |
62 bool reuse = true; | |
63 UDT::setsockopt(usock, 0, UDT_REUSEADDR, &reuse, sizeof(bool)); | |
64 UDT::setsockopt(usock, 0, UDT_RENDEZVOUS, &rendezvous, sizeof(bool)); | |
65 | |
66 if (UDT::ERROR == UDT::bind(usock, res->ai_addr, res->ai_addrlen)) | |
67 { | |
68 cout << "bind: " << UDT::getlasterror().getErrorMessage() << endl; | |
69 return -1; | |
70 } | |
71 | |
72 freeaddrinfo(res); | |
73 return 0; | |
74 } | |
75 | |
76 int createTCPSocket(SYSSOCKET& ssock, int version = AF_INET, int type = SOCK_STR
EAM, int port = 0, bool rendezvous = false) | |
77 { | |
78 addrinfo hints; | |
79 addrinfo* res; | |
80 | |
81 memset(&hints, 0, sizeof(struct addrinfo)); | |
82 | |
83 hints.ai_flags = AI_PASSIVE; | |
84 hints.ai_family = version; | |
85 hints.ai_socktype = type; | |
86 | |
87 char service[16]; | |
88 sprintf(service, "%d", port); | |
89 | |
90 if (0 != getaddrinfo(NULL, service, &hints, &res)) | |
91 { | |
92 cout << "illegal port number or port is busy.\n" << endl; | |
93 return -1; | |
94 } | |
95 | |
96 ssock = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | |
97 | |
98 if (bind(ssock, res->ai_addr, res->ai_addrlen) != 0) | |
99 { | |
100 return -1; | |
101 } | |
102 | |
103 freeaddrinfo(res); | |
104 return 0; | |
105 } | |
106 | |
107 int connect(UDTSOCKET& usock, int port, int version, int type) | |
108 { | |
109 addrinfo hints, *peer; | |
110 | |
111 memset(&hints, 0, sizeof(struct addrinfo)); | |
112 | |
113 hints.ai_flags = AI_PASSIVE; | |
114 hints.ai_family = version; | |
115 hints.ai_socktype = type; | |
116 | |
117 char buffer[16]; | |
118 sprintf(buffer, "%d", port); | |
119 | |
120 if (0 != getaddrinfo("127.0.0.1", buffer, &hints, &peer)) | |
121 { | |
122 return 0; | |
123 } | |
124 | |
125 UDT::connect(usock, peer->ai_addr, peer->ai_addrlen); | |
126 | |
127 freeaddrinfo(peer); | |
128 | |
129 return 0; | |
130 } | |
131 | |
132 int tcp_connect(SYSSOCKET& ssock, int port, int version, int type) | |
133 { | |
134 addrinfo hints, *peer; | |
135 | |
136 memset(&hints, 0, sizeof(struct addrinfo)); | |
137 | |
138 hints.ai_flags = AI_PASSIVE; | |
139 hints.ai_family = version; | |
140 hints.ai_socktype = type; | |
141 | |
142 char buffer[16]; | |
143 sprintf(buffer, "%d", port); | |
144 | |
145 if (0 != getaddrinfo("127.0.0.1", buffer, &hints, &peer)) | |
146 { | |
147 return 0; | |
148 } | |
149 | |
150 connect(ssock, peer->ai_addr, peer->ai_addrlen); | |
151 | |
152 freeaddrinfo(peer); | |
153 | |
154 return 0; | |
155 } | |
156 | |
157 | |
158 #ifndef WIN32 | |
159 void* Test_1_Srv(void* param) | |
160 #else | |
161 DWORD WINAPI Test_1_Srv(LPVOID param) | |
162 #endif | |
163 { | |
164 UDTSOCKET serv; | |
165 if (createUDTSocket(serv, AF_INET, SOCK_STREAM, 9000) < 0) | |
166 return NULL; | |
167 | |
168 UDT::listen(serv, 10); | |
169 | |
170 sockaddr_storage clientaddr; | |
171 int addrlen = sizeof(clientaddr); | |
172 UDTSOCKET new_sock = UDT::accept(serv, (sockaddr*)&clientaddr, &addrlen); | |
173 | |
174 UDT::close(serv); | |
175 | |
176 if (new_sock == UDT::INVALID_SOCK) | |
177 { | |
178 return NULL; | |
179 } | |
180 | |
181 const int size = 10000; | |
182 int32_t buffer[size]; | |
183 fill_n(buffer, 0, size); | |
184 | |
185 int torecv = size * sizeof(int32_t); | |
186 while (torecv > 0) | |
187 { | |
188 int rcvd = UDT::recv(new_sock, (char*)buffer + size * sizeof(int32_t) - to
recv, torecv, 0); | |
189 if (rcvd < 0) | |
190 { | |
191 cout << "recv: " << UDT::getlasterror().getErrorMessage() << endl; | |
192 return NULL; | |
193 } | |
194 | |
195 torecv -= rcvd; | |
196 } | |
197 | |
198 // check data | |
199 for (int i = 0; i < size; ++ i) | |
200 { | |
201 if (buffer[i] != i) | |
202 { | |
203 cout << "DATA ERROR " << i << " " << buffer[i] << endl; | |
204 break; | |
205 } | |
206 } | |
207 | |
208 UDT::close(new_sock); | |
209 | |
210 return NULL; | |
211 } | |
212 | |
213 #ifndef WIN32 | |
214 void* Test_1_Cli(void* param) | |
215 #else | |
216 DWORD WINAPI Test_1_Cli(LPVOID param) | |
217 #endif | |
218 { | |
219 UDTSOCKET client; | |
220 if (createUDTSocket(client, AF_INET, SOCK_STREAM, 0) < 0) | |
221 return NULL; | |
222 | |
223 connect(client, 9000, AF_INET, SOCK_STREAM); | |
224 | |
225 const int size = 10000; | |
226 int32_t buffer[size]; | |
227 for (int i = 0; i < size; ++ i) | |
228 buffer[i] = i; | |
229 | |
230 int tosend = size * sizeof(int32_t); | |
231 while (tosend > 0) | |
232 { | |
233 int sent = UDT::send(client, (char*)buffer + size * sizeof(int32_t) - tose
nd, tosend, 0); | |
234 if (sent < 0) | |
235 { | |
236 cout << "send: " << UDT::getlasterror().getErrorMessage() << endl; | |
237 return NULL; | |
238 } | |
239 | |
240 tosend -= sent; | |
241 } | |
242 | |
243 UDT::close(client); | |
244 return NULL; | |
245 } | |
246 | |
247 #ifndef WIN32 | |
248 void* Test_2_Srv(void* param) | |
249 #else | |
250 DWORD WINAPI Test_2_Srv(LPVOID param) | |
251 #endif | |
252 { | |
253 #ifndef WIN32 | |
254 //ignore SIGPIPE | |
255 sigset_t ps; | |
256 sigemptyset(&ps); | |
257 sigaddset(&ps, SIGPIPE); | |
258 pthread_sigmask(SIG_BLOCK, &ps, NULL); | |
259 #endif | |
260 | |
261 // create 1000 UDT sockets | |
262 UDTSOCKET serv; | |
263 if (createUDTSocket(serv, AF_INET, SOCK_STREAM, 9000) < 0) | |
264 return NULL; | |
265 | |
266 UDT::listen(serv, 10); | |
267 | |
268 vector<UDTSOCKET> new_socks; | |
269 new_socks.resize(1000); | |
270 | |
271 int eid = UDT::epoll_create(); | |
272 | |
273 for (int i = 0; i < 1000; ++ i) | |
274 { | |
275 sockaddr_storage clientaddr; | |
276 int addrlen = sizeof(clientaddr); | |
277 new_socks[i] = UDT::accept(serv, (sockaddr*)&clientaddr, &addrlen); | |
278 | |
279 if (new_socks[i] == UDT::INVALID_SOCK) | |
280 { | |
281 cout << "accept: " << UDT::getlasterror().getErrorMessage() << endl; | |
282 return NULL; | |
283 } | |
284 | |
285 UDT::epoll_add_usock(eid, new_socks[i]); | |
286 } | |
287 | |
288 | |
289 // create 10 TCP sockets | |
290 SYSSOCKET tcp_serv; | |
291 if (createTCPSocket(tcp_serv, AF_INET, SOCK_STREAM, 9001) < 0) | |
292 return NULL; | |
293 | |
294 listen(tcp_serv, 10); | |
295 | |
296 vector<SYSSOCKET> tcp_socks; | |
297 tcp_socks.resize(10); | |
298 | |
299 for (int i = 0; i < 10; ++ i) | |
300 { | |
301 sockaddr_storage clientaddr; | |
302 socklen_t addrlen = sizeof(clientaddr); | |
303 tcp_socks[i] = accept(tcp_serv, (sockaddr*)&clientaddr, &addrlen); | |
304 | |
305 UDT::epoll_add_ssock(eid, tcp_socks[i]); | |
306 } | |
307 | |
308 | |
309 // using epoll to retrieve both UDT and TCP sockets | |
310 set<UDTSOCKET> readfds; | |
311 set<SYSSOCKET> tcpread; | |
312 int count = 1000 + 10; | |
313 while (count > 0) | |
314 { | |
315 UDT::epoll_wait(eid, &readfds, NULL, -1, &tcpread); | |
316 for (set<UDTSOCKET>::iterator i = readfds.begin(); i != readfds.end(); ++
i) | |
317 { | |
318 int32_t data; | |
319 UDT::recv(*i, (char*)&data, 4, 0); | |
320 | |
321 -- count; | |
322 } | |
323 | |
324 for (set<SYSSOCKET>::iterator i = tcpread.begin(); i != tcpread.end(); ++
i) | |
325 { | |
326 int32_t data; | |
327 recv(*i, (char*)&data, 4, 0); | |
328 | |
329 -- count; | |
330 } | |
331 } | |
332 | |
333 for (vector<UDTSOCKET>::iterator i = new_socks.begin(); i != new_socks.end();
++ i) | |
334 { | |
335 UDT::close(*i); | |
336 } | |
337 | |
338 for (vector<SYSSOCKET>::iterator i = tcp_socks.begin(); i != tcp_socks.end();
++ i) | |
339 { | |
340 #ifndef WIN32 | |
341 close(*i); | |
342 #else | |
343 closesocket(*i); | |
344 #endif | |
345 } | |
346 | |
347 UDT::close(serv); | |
348 #ifndef WIN32 | |
349 close(tcp_serv); | |
350 #else | |
351 closesocket(tcp_serv); | |
352 #endif | |
353 | |
354 return NULL; | |
355 } | |
356 | |
357 #ifndef WIN32 | |
358 void* Test_2_Cli(void* param) | |
359 #else | |
360 DWORD WINAPI Test_2_Cli(LPVOID param) | |
361 #endif | |
362 { | |
363 #ifndef WIN32 | |
364 //ignore SIGPIPE | |
365 sigset_t ps; | |
366 sigemptyset(&ps); | |
367 sigaddset(&ps, SIGPIPE); | |
368 pthread_sigmask(SIG_BLOCK, &ps, NULL); | |
369 #endif | |
370 | |
371 // create 1000 UDT clients | |
372 vector<UDTSOCKET> cli_socks; | |
373 cli_socks.resize(1000); | |
374 | |
375 // 100 individual ports | |
376 for (int i = 0; i < 100; ++ i) | |
377 { | |
378 if (createUDTSocket(cli_socks[i], AF_INET, SOCK_STREAM, 0) < 0) | |
379 { | |
380 cout << "socket: " << UDT::getlasterror().getErrorMessage() << endl; | |
381 return NULL; | |
382 } | |
383 } | |
384 | |
385 // 900 shared port | |
386 | |
387 if (createUDTSocket(cli_socks[100], AF_INET, SOCK_STREAM, 0) < 0) | |
388 { | |
389 cout << "socket: " << UDT::getlasterror().getErrorMessage() << endl; | |
390 return NULL; | |
391 } | |
392 | |
393 sockaddr* addr = NULL; | |
394 int size = 0; | |
395 | |
396 addr = (sockaddr*)new sockaddr_in; | |
397 size = sizeof(sockaddr_in); | |
398 | |
399 UDT::getsockname(cli_socks[100], addr, &size); | |
400 char sharedport[NI_MAXSERV]; | |
401 getnameinfo(addr, size, NULL, 0, sharedport, sizeof(sharedport), NI_NUMERICSE
RV); | |
402 | |
403 for (int i = 101; i < 1000; ++ i) | |
404 { | |
405 if (createUDTSocket(cli_socks[i], AF_INET, SOCK_STREAM, atoi(sharedport))
< 0) | |
406 { | |
407 cout << "socket: " << UDT::getlasterror().getErrorMessage() << endl; | |
408 return NULL; | |
409 } | |
410 } | |
411 | |
412 for (vector<UDTSOCKET>::iterator i = cli_socks.begin(); i != cli_socks.end();
++ i) | |
413 { | |
414 if (connect(*i, 9000, AF_INET, SOCK_STREAM) < 0) | |
415 { | |
416 cout << "connect: " << UDT::getlasterror().getErrorMessage() << endl; | |
417 return NULL; | |
418 } | |
419 } | |
420 | |
421 | |
422 // create 10 TCP clients | |
423 vector<SYSSOCKET> tcp_socks; | |
424 tcp_socks.resize(10); | |
425 | |
426 for (int i = 0; i < 10; ++ i) | |
427 { | |
428 if (createTCPSocket(tcp_socks[i], AF_INET, SOCK_STREAM, 0) < 0) | |
429 { | |
430 return NULL; | |
431 } | |
432 | |
433 tcp_connect(tcp_socks[i], 9001, AF_INET, SOCK_STREAM); | |
434 } | |
435 | |
436 | |
437 // send data from both UDT and TCP clients | |
438 int32_t data = 0; | |
439 for (vector<UDTSOCKET>::iterator i = cli_socks.begin(); i != cli_socks.end();
++ i) | |
440 { | |
441 UDT::send(*i, (char*)&data, 4, 0); | |
442 ++ data; | |
443 } | |
444 | |
445 for (vector<SYSSOCKET>::iterator i = tcp_socks.begin(); i != tcp_socks.end();
++ i) | |
446 { | |
447 send(*i, (char*)&data, 4, 0); | |
448 ++ data; | |
449 } | |
450 | |
451 | |
452 // close all client sockets | |
453 for (vector<UDTSOCKET>::iterator i = cli_socks.begin(); i != cli_socks.end();
++ i) | |
454 { | |
455 UDT::close(*i); | |
456 } | |
457 | |
458 for (vector<SYSSOCKET>::iterator i = tcp_socks.begin(); i != tcp_socks.end();
++ i) | |
459 { | |
460 #ifndef WIN32 | |
461 close(*i); | |
462 #else | |
463 closesocket(*i); | |
464 #endif | |
465 } | |
466 | |
467 return NULL; | |
468 } | |
469 | |
470 #ifndef WIN32 | |
471 void* Test_3_Srv(void* param) | |
472 #else | |
473 DWORD WINAPI Test_3_Srv(LPVOID param) | |
474 #endif | |
475 { | |
476 vector<UDTSOCKET> srv_socks; | |
477 srv_socks.resize(50); | |
478 | |
479 int port = 61000; | |
480 | |
481 for (int i = 0; i < 50; ++ i) | |
482 { | |
483 if (createUDTSocket(srv_socks[i], AF_INET, SOCK_STREAM, port ++, true) < 0
) | |
484 { | |
485 cout << "error\n"; | |
486 } | |
487 } | |
488 | |
489 int peer_port = 51000; | |
490 | |
491 for (vector<UDTSOCKET>::iterator i = srv_socks.begin(); i != srv_socks.end();
++ i) | |
492 { | |
493 connect(*i, peer_port ++, AF_INET, SOCK_STREAM); | |
494 } | |
495 | |
496 for (vector<UDTSOCKET>::iterator i = srv_socks.begin(); i != srv_socks.end();
++ i) | |
497 { | |
498 int32_t data = 0; | |
499 UDT::recv(*i, (char*)&data, 4, 0); | |
500 } | |
501 | |
502 for (vector<UDTSOCKET>::iterator i = srv_socks.begin(); i != srv_socks.end();
++ i) | |
503 { | |
504 UDT::close(*i); | |
505 } | |
506 | |
507 return NULL; | |
508 } | |
509 | |
510 #ifndef WIN32 | |
511 void* Test_3_Cli(void* param) | |
512 #else | |
513 DWORD WINAPI Test_3_Cli(LPVOID param) | |
514 #endif | |
515 { | |
516 vector<UDTSOCKET> cli_socks; | |
517 cli_socks.resize(50); | |
518 | |
519 int port = 51000; | |
520 | |
521 for (int i = 0; i < 50; ++ i) | |
522 { | |
523 if (createUDTSocket(cli_socks[i], AF_INET, SOCK_STREAM, port ++, true) < 0
) | |
524 { | |
525 cout << "error\n"; | |
526 } | |
527 } | |
528 | |
529 int peer_port = 61000; | |
530 | |
531 for (vector<UDTSOCKET>::iterator i = cli_socks.begin(); i != cli_socks.end();
++ i) | |
532 { | |
533 connect(*i, peer_port ++, AF_INET, SOCK_STREAM); | |
534 } | |
535 | |
536 int32_t data = 0; | |
537 for (vector<UDTSOCKET>::iterator i = cli_socks.begin(); i != cli_socks.end();
++ i) | |
538 { | |
539 UDT::send(*i, (char*)&data, 4, 0); | |
540 ++ data; | |
541 } | |
542 | |
543 for (vector<UDTSOCKET>::iterator i = cli_socks.begin(); i != cli_socks.end();
++ i) | |
544 { | |
545 UDT::close(*i); | |
546 } | |
547 | |
548 return NULL; | |
549 } | |
550 | |
551 #ifndef WIN32 | |
552 void* Test_4_Srv(void* param) | |
553 #else | |
554 DWORD WINAPI Test_4_Srv(LPVOID param) | |
555 #endif | |
556 { | |
557 UDTSOCKET serv; | |
558 if (createUDTSocket(serv, AF_INET, SOCK_STREAM, 9000) < 0) | |
559 return NULL; | |
560 | |
561 UDT::listen(serv, 10); | |
562 | |
563 const int total = 1000; | |
564 | |
565 vector<UDTSOCKET> new_socks; | |
566 new_socks.resize(total); | |
567 | |
568 for (int i = 0; i < total; ++ i) | |
569 { | |
570 sockaddr_storage clientaddr; | |
571 int addrlen = sizeof(clientaddr); | |
572 new_socks[i] = UDT::accept(serv, (sockaddr*)&clientaddr, &addrlen); | |
573 | |
574 if (new_socks[i] == UDT::INVALID_SOCK) | |
575 { | |
576 cout << "accept: " << UDT::getlasterror().getErrorMessage() << endl; | |
577 return NULL; | |
578 } | |
579 } | |
580 | |
581 for (vector<UDTSOCKET>::iterator i = new_socks.begin(); i != new_socks.end();
++ i) | |
582 { | |
583 UDT::close(*i); | |
584 } | |
585 | |
586 UDT::close(serv); | |
587 | |
588 return NULL; | |
589 | |
590 } | |
591 | |
592 #ifndef WIN32 | |
593 void* start_and_destroy_clients(void* param) | |
594 #else | |
595 DWORD WINAPI start_and_destroy_clients(LPVOID param) | |
596 #endif | |
597 { | |
598 const int total = 25; | |
599 | |
600 vector<UDTSOCKET> cli_socks; | |
601 cli_socks.resize(total); | |
602 | |
603 if (createUDTSocket(cli_socks[0], AF_INET, SOCK_STREAM, 0) < 0) | |
604 { | |
605 cout << "socket: " << UDT::getlasterror().getErrorMessage() << endl; | |
606 return NULL; | |
607 } | |
608 | |
609 sockaddr* addr = NULL; | |
610 int size = 0; | |
611 | |
612 addr = (sockaddr*)new sockaddr_in; | |
613 size = sizeof(sockaddr_in); | |
614 | |
615 UDT::getsockname(cli_socks[0], addr, &size); | |
616 char sharedport[NI_MAXSERV]; | |
617 getnameinfo(addr, size, NULL, 0, sharedport, sizeof(sharedport), NI_NUMERICSE
RV); | |
618 | |
619 for (int i = 1; i < total; ++ i) | |
620 { | |
621 if (createUDTSocket(cli_socks[i], AF_INET, SOCK_STREAM, atoi(sharedport))
< 0) | |
622 { | |
623 cout << "socket: " << UDT::getlasterror().getErrorMessage() << endl; | |
624 return NULL; | |
625 } | |
626 } | |
627 | |
628 for (vector<UDTSOCKET>::iterator i = cli_socks.begin(); i != cli_socks.end();
++ i) | |
629 { | |
630 if (connect(*i, 9000, AF_INET, SOCK_STREAM) < 0) | |
631 { | |
632 cout << "connect: " << UDT::getlasterror().getErrorMessage() << endl; | |
633 return NULL; | |
634 } | |
635 } | |
636 | |
637 for (vector<UDTSOCKET>::iterator i = cli_socks.begin(); i != cli_socks.end();
++ i) | |
638 { | |
639 UDT::close(*i); | |
640 } | |
641 | |
642 return NULL; | |
643 } | |
644 | |
645 #ifndef WIN32 | |
646 void* Test_4_Cli(void*) | |
647 #else | |
648 DWORD WINAPI Test_4_Cli(LPVOID) | |
649 #endif | |
650 { | |
651 const int total_threads = 40; // 40 * 25 = 1000 | |
652 | |
653 #ifndef WIN32 | |
654 vector<pthread_t> cli_threads; | |
655 cli_threads.resize(total_threads); | |
656 | |
657 for (vector<pthread_t>::iterator i = cli_threads.begin(); i != cli_threads.en
d(); ++ i) | |
658 { | |
659 pthread_create(&(*i), NULL, start_and_destroy_clients, NULL); | |
660 } | |
661 | |
662 for (vector<pthread_t>::iterator i = cli_threads.begin(); i != cli_threads.en
d(); ++ i) | |
663 { | |
664 pthread_join(*i, NULL); | |
665 } | |
666 #else | |
667 vector<HANDLE> cli_threads; | |
668 cli_threads.resize(total_threads); | |
669 | |
670 for (vector<HANDLE>::iterator i = cli_threads.begin(); i != cli_threads.end()
; ++ i) | |
671 { | |
672 *i = CreateThread(NULL, 0, NULL, start_and_destroy_clients, 0, NULL); | |
673 } | |
674 | |
675 for (vector<HANDLE>::iterator i = cli_threads.begin(); i != cli_threads.end()
; ++ i) | |
676 { | |
677 WaitForSingleObject(*i, INFINITE); | |
678 } | |
679 #endif | |
680 | |
681 return NULL; | |
682 } | |
683 | |
684 | |
685 int main() | |
686 { | |
687 const int test_case = 4; | |
688 | |
689 #ifndef WIN32 | |
690 void* (*Test_Srv[test_case])(void*); | |
691 void* (*Test_Cli[test_case])(void*); | |
692 #else | |
693 DWORD (WINAPI *Test_Srv[test_case])(LPVOID); | |
694 DWORD (WINAPI *Test_Cli[test_case])(LPVOID); | |
695 #endif | |
696 | |
697 Test_Srv[0] = Test_1_Srv; | |
698 Test_Cli[0] = Test_1_Cli; | |
699 Test_Srv[1] = Test_2_Srv; | |
700 Test_Cli[1] = Test_2_Cli; | |
701 Test_Srv[2] = Test_3_Srv; | |
702 Test_Cli[2] = Test_3_Cli; | |
703 Test_Srv[3] = Test_4_Srv; | |
704 Test_Cli[3] = Test_4_Cli; | |
705 | |
706 for (int i = 0; i < test_case; ++ i) | |
707 { | |
708 cout << "Start Test # " << i + 1 << endl; | |
709 | |
710 UDT::startup(); | |
711 | |
712 #ifndef WIN32 | |
713 pthread_t srv, cli; | |
714 pthread_create(&srv, NULL, Test_Srv[i], NULL); | |
715 pthread_create(&cli, NULL, Test_Cli[i], NULL); | |
716 | |
717 pthread_join(srv, NULL); | |
718 pthread_join(cli, NULL); | |
719 #else | |
720 HANDLE srv, cli; | |
721 srv = CreateThread(NULL, 0, Test_Srv[i], NULL, 0, NULL); | |
722 cli = CreateThread(NULL, 0, Test_Cli[i], NULL, 0, NULL); | |
723 | |
724 WaitForSingleObject(srv, INFINITE); | |
725 WaitForSingleObject(cli, INFINITE); | |
726 #endif | |
727 | |
728 UDT::cleanup(); | |
729 | |
730 cout << "Test # " << i + 1 << " completed." << endl; | |
731 } | |
732 | |
733 return 0; | |
734 } | |
OLD | NEW |