2 * Unit test suite for winsock functions
4 * Copyright 2002 Martin Wilck
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "wine/test.h"
31 #define MAX_CLIENTS 4 /* Max number of clients */
32 #define NUM_TESTS 2 /* Number of tests performed */
33 #define FIRST_CHAR 'A' /* First character in transferred pattern */
34 #define BIND_SLEEP 10 /* seconds to wait between attempts to bind() */
35 #define BIND_TRIES 6 /* Number of bind() attempts */
36 #define TEST_TIMEOUT 30 /* seconds to wait before killing child threads
37 after server initialization, if something hangs */
39 #define wsa_ok(op, cond, msg) \
43 if ( !(cond tmp) ) err = WSAGetLastError(); \
44 ok ( cond tmp, msg, GetCurrentThreadId(), err); \
48 /**************** Structs and typedefs ***************/
50 typedef struct thread_info
56 /* Information in the server about open client connections */
57 typedef struct sock_info
60 struct sockaddr_in addr
;
61 struct sockaddr_in peer
;
66 /* Test parameters for both server & client */
67 typedef struct test_params
71 const char *inet_addr
;
78 /* server-specific test parameters */
79 typedef struct server_params
86 /* client-specific test parameters */
87 typedef struct client_params
94 /* This type combines all information for setting up a test scenario */
95 typedef struct test_setup
99 server_params srv_params
;
101 client_params clt_params
;
104 /* Thread local storage for server */
105 typedef struct server_memory
108 struct sockaddr_in addr
;
109 sock_info sock
[MAX_CLIENTS
];
112 /* Thread local storage for client */
113 typedef struct client_memory
116 struct sockaddr_in addr
;
121 /**************** Static variables ***************/
123 static DWORD tls
; /* Thread local storage index */
124 static HANDLE thread
[1+MAX_CLIENTS
];
125 static DWORD thread_id
[1+MAX_CLIENTS
];
126 static HANDLE server_ready
;
127 static HANDLE client_ready
[MAX_CLIENTS
];
128 static int client_id
;
130 /**************** General utility functions ***************/
132 static void set_so_opentype ( BOOL overlapped
)
134 int optval
= !overlapped
, newval
, len
= sizeof (int);
136 ok ( setsockopt ( INVALID_SOCKET
, SOL_SOCKET
, SO_OPENTYPE
,
137 (LPVOID
) &optval
, sizeof (optval
) ) == 0,
138 "setting SO_OPENTYPE failed\n" );
139 ok ( getsockopt ( INVALID_SOCKET
, SOL_SOCKET
, SO_OPENTYPE
,
140 (LPVOID
) &newval
, &len
) == 0,
141 "getting SO_OPENTYPE failed\n" );
142 ok ( optval
== newval
, "failed to set SO_OPENTYPE\n" );
145 static int set_blocking ( SOCKET s
, BOOL blocking
)
147 u_long val
= !blocking
;
148 return ioctlsocket ( s
, FIONBIO
, &val
);
151 static void fill_buffer ( char *buf
, int chunk_size
, int n_chunks
)
154 for ( c
= FIRST_CHAR
, p
= buf
; c
< FIRST_CHAR
+ n_chunks
; c
++, p
+= chunk_size
)
155 memset ( p
, c
, chunk_size
);
158 static char* test_buffer ( char *buf
, int chunk_size
, int n_chunks
)
162 for ( c
= FIRST_CHAR
, p
= buf
; c
< FIRST_CHAR
+ n_chunks
; c
++, p
+= chunk_size
)
164 for ( i
= 0; i
< chunk_size
; i
++ )
165 if ( p
[i
] != c
) return p
+ i
;
171 * This routine is called when a client / server does not expect any more data,
172 * but needs to acknowedge the closing of the connection (by reasing 0 bytes).
174 static void read_zero_bytes ( SOCKET s
)
178 while ( ( tmp
= recv ( s
, buf
, 256, 0 ) ) > 0 )
180 ok ( n
<= 0, "garbage data received: %d bytes\n", n
);
183 static int do_synchronous_send ( SOCKET s
, char *buf
, int buflen
, int sendlen
)
185 char* last
= buf
+ buflen
, *p
;
187 for ( p
= buf
; n
> 0 && p
< last
; p
+= n
)
188 n
= send ( s
, p
, min ( sendlen
, last
- p
), 0 );
189 wsa_ok ( n
, 0 <=, "do_synchronous_send (%lx): error %d\n" );
193 static int do_synchronous_recv ( SOCKET s
, char *buf
, int buflen
, int recvlen
)
195 char* last
= buf
+ buflen
, *p
;
197 for ( p
= buf
; n
> 0 && p
< last
; p
+= n
)
198 n
= recv ( s
, p
, min ( recvlen
, last
- p
), 0 );
199 wsa_ok ( n
, 0 <=, "do_synchronous_recv (%lx): error %d:\n" );
204 * Call this routine right after thread startup.
205 * SO_OPENTYPE must by 0, regardless what the server did.
207 static void check_so_opentype (void)
211 getsockopt ( INVALID_SOCKET
, SOL_SOCKET
, SO_OPENTYPE
, (LPVOID
) &tmp
, &len
);
212 ok ( tmp
== 0, "check_so_opentype: wrong startup value of SO_OPENTYPE: %d\n", tmp
);
215 /**************** Server utility functions ***************/
218 * Even if we have closed our server socket cleanly,
219 * the OS may mark the address "in use" for some time -
220 * this happens with native Linux apps, too.
222 static void do_bind ( SOCKET s
, struct sockaddr
* addr
, int addrlen
)
224 int err
, wsaerr
= 0, n_try
= BIND_TRIES
;
226 while ( ( err
= bind ( s
, addr
, addrlen
) ) != 0 &&
227 ( wsaerr
= WSAGetLastError () ) == WSAEADDRINUSE
&&
230 trace ( "address in use, waiting ...\n" );
231 Sleep ( 1000 * BIND_SLEEP
);
233 ok ( err
== 0, "failed to bind: %d\n", wsaerr
);
236 static void server_start ( server_params
*par
)
239 test_params
*gen
= par
->general
;
240 server_memory
*mem
= (LPVOID
) LocalAlloc ( LPTR
, sizeof (server_memory
));
242 TlsSetValue ( tls
, mem
);
243 mem
->s
= WSASocketA ( AF_INET
, gen
->sock_type
, gen
->sock_prot
,
244 NULL
, 0, par
->sock_flags
);
245 ok ( mem
->s
!= INVALID_SOCKET
, "Server: WSASocket failed\n" );
247 mem
->addr
.sin_family
= AF_INET
;
248 mem
->addr
.sin_addr
.s_addr
= inet_addr ( gen
->inet_addr
);
249 mem
->addr
.sin_port
= htons ( gen
->inet_port
);
251 for (i
= 0; i
< MAX_CLIENTS
; i
++)
253 mem
->sock
[i
].s
= INVALID_SOCKET
;
254 mem
->sock
[i
].buf
= (LPVOID
) LocalAlloc ( LPTR
, gen
->n_chunks
* gen
->chunk_size
);
255 mem
->sock
[i
].nread
= 0;
258 if ( gen
->sock_type
== SOCK_STREAM
)
259 do_bind ( mem
->s
, (struct sockaddr
*) &mem
->addr
, sizeof (mem
->addr
) );
262 static void server_stop (void)
265 server_memory
*mem
= TlsGetValue ( tls
);
267 for (i
= 0; i
< MAX_CLIENTS
; i
++ )
269 LocalFree ( (HANDLE
) mem
->sock
[i
].buf
);
270 if ( mem
->sock
[i
].s
!= INVALID_SOCKET
)
271 closesocket ( mem
->sock
[i
].s
);
273 ok ( closesocket ( mem
->s
) == 0, "closesocket failed\n" );
274 LocalFree ( (HANDLE
) mem
);
275 ExitThread ( GetCurrentThreadId () );
278 /**************** Client utilitiy functions ***************/
280 static void client_start ( client_params
*par
)
282 test_params
*gen
= par
->general
;
283 client_memory
*mem
= (LPVOID
) LocalAlloc (LPTR
, sizeof (client_memory
));
285 TlsSetValue ( tls
, mem
);
287 WaitForSingleObject ( server_ready
, INFINITE
);
289 mem
->s
= WSASocketA ( AF_INET
, gen
->sock_type
, gen
->sock_prot
,
290 NULL
, 0, par
->sock_flags
);
292 mem
->addr
.sin_family
= AF_INET
;
293 mem
->addr
.sin_addr
.s_addr
= inet_addr ( gen
->inet_addr
);
294 mem
->addr
.sin_port
= htons ( gen
->inet_port
);
296 ok ( mem
->s
!= INVALID_SOCKET
, "Client: WSASocket failed\n" );
298 mem
->send_buf
= (LPVOID
) LocalAlloc ( LPTR
, 2 * gen
->n_chunks
* gen
->chunk_size
);
299 mem
->recv_buf
= mem
->send_buf
+ gen
->n_chunks
* gen
->chunk_size
;
300 fill_buffer ( mem
->send_buf
, gen
->chunk_size
, gen
->n_chunks
);
302 SetEvent ( client_ready
[client_id
] );
303 /* Wait for the other clients to come up */
304 WaitForMultipleObjects ( min ( gen
->n_clients
, MAX_CLIENTS
), client_ready
, TRUE
, INFINITE
);
307 static void client_stop (void)
309 client_memory
*mem
= TlsGetValue ( tls
);
310 wsa_ok ( closesocket ( mem
->s
), 0 ==, "closesocket error (%lx): %d\n" );
311 LocalFree ( (HANDLE
) mem
->send_buf
);
312 LocalFree ( (HANDLE
) mem
);
316 /**************** Servers ***************/
319 * simple_server: A very basic server doing synchronous IO.
321 static VOID WINAPI
simple_server ( server_params
*par
)
323 test_params
*gen
= par
->general
;
325 int n_recvd
, n_sent
, n_expected
= gen
->n_chunks
* gen
->chunk_size
, tmp
, i
,
326 id
= GetCurrentThreadId();
329 trace ( "simple_server (%x) starting\n", id
);
331 set_so_opentype ( FALSE
); /* non-overlapped */
332 server_start ( par
);
333 mem
= TlsGetValue ( tls
);
335 wsa_ok ( set_blocking ( mem
->s
, TRUE
), 0 ==, "simple_server (%lx): failed to set blocking mode: %d\n");
336 wsa_ok ( listen ( mem
->s
, SOMAXCONN
), 0 ==, "simple_server (%lx): listen failed: %d\n");
338 trace ( "simple_server (%x) ready\n", id
);
339 SetEvent ( server_ready
); /* notify clients */
341 for ( i
= 0; i
< min ( gen
->n_clients
, MAX_CLIENTS
); i
++ )
343 trace ( "simple_server (%x): waiting for client\n", id
);
345 /* accept a single connection */
346 tmp
= sizeof ( mem
->sock
[0].peer
);
347 mem
->sock
[0].s
= accept ( mem
->s
, (struct sockaddr
*) &mem
->sock
[0].peer
, &tmp
);
348 wsa_ok ( mem
->sock
[0].s
, INVALID_SOCKET
!=, "simple_server (%lx): accept failed: %d\n" );
350 ok ( mem
->sock
[0].peer
.sin_addr
.s_addr
== inet_addr ( gen
->inet_addr
),
351 "simple_server (%x): strange peer address\n", id
);
353 /* Receive data & check it */
354 n_recvd
= do_synchronous_recv ( mem
->sock
[0].s
, mem
->sock
[0].buf
, n_expected
, par
->buflen
);
355 ok ( n_recvd
== n_expected
,
356 "simple_server (%x): received less data than expected: %d of %d\n", id
, n_recvd
, n_expected
);
357 p
= test_buffer ( mem
->sock
[0].buf
, gen
->chunk_size
, gen
->n_chunks
);
358 ok ( p
== NULL
, "simple_server (%x): test pattern error: %d\n", id
, p
- mem
->sock
[0].buf
);
361 n_sent
= do_synchronous_send ( mem
->sock
[0].s
, mem
->sock
[0].buf
, n_expected
, par
->buflen
);
362 ok ( n_sent
== n_expected
,
363 "simple_server (%x): sent less data than expected: %d of %d\n", id
, n_sent
, n_expected
);
366 read_zero_bytes ( mem
->sock
[0].s
);
367 wsa_ok ( closesocket ( mem
->sock
[0].s
), 0 ==, "simple_server (%lx): closesocket error: %d\n" );
368 mem
->sock
[0].s
= INVALID_SOCKET
;
371 trace ( "simple_server (%x) exiting\n", id
);
375 /**************** Clients ***************/
378 * simple_client: A very basic client doing synchronous IO.
380 static VOID WINAPI
simple_client ( client_params
*par
)
382 test_params
*gen
= par
->general
;
384 int n_sent
, n_recvd
, n_expected
= gen
->n_chunks
* gen
->chunk_size
, id
;
387 id
= GetCurrentThreadId();
388 trace ( "simple_client (%x): starting\n", id
);
389 /* wait here because we want to call set_so_opentype before creating a socket */
390 WaitForSingleObject ( server_ready
, INFINITE
);
391 trace ( "simple_client (%x): server ready\n", id
);
393 check_so_opentype ();
394 set_so_opentype ( FALSE
); /* non-overlapped */
395 client_start ( par
);
396 mem
= TlsGetValue ( tls
);
399 wsa_ok ( connect ( mem
->s
, (struct sockaddr
*) &mem
->addr
, sizeof ( mem
->addr
) ),
400 0 ==, "simple_client (%lx): connect error: %d\n" );
401 ok ( set_blocking ( mem
->s
, TRUE
) == 0,
402 "simple_client (%x): failed to set blocking mode\n", id
);
403 trace ( "simple_client (%x) connected\n", id
);
405 /* send data to server */
406 n_sent
= do_synchronous_send ( mem
->s
, mem
->send_buf
, n_expected
, par
->buflen
);
407 ok ( n_sent
== n_expected
,
408 "simple_client (%x): sent less data than expected: %d of %d\n", id
, n_sent
, n_expected
);
410 /* shutdown send direction */
411 wsa_ok ( shutdown ( mem
->s
, SD_SEND
), 0 ==, "simple_client (%lx): shutdown failed: %d\n" );
413 /* Receive data echoed back & check it */
414 n_recvd
= do_synchronous_recv ( mem
->s
, mem
->recv_buf
, n_expected
, par
->buflen
);
415 ok ( n_recvd
== n_expected
,
416 "simple_client (%x): received less data than expected: %d of %d\n", id
, n_recvd
, n_expected
);
419 p
= test_buffer ( mem
->recv_buf
, gen
->chunk_size
, gen
->n_chunks
);
420 ok ( p
== NULL
, "simple_client (%x): test pattern error: %d\n", id
, p
- mem
->recv_buf
);
423 read_zero_bytes ( mem
->s
);
424 trace ( "simple_client (%x) exiting\n", id
);
429 * event_client: An event-driven client
431 static void WINAPI
event_client ( client_params
*par
)
433 test_params
*gen
= par
->general
;
435 int id
= GetCurrentThreadId(), n_expected
= gen
->n_chunks
* gen
->chunk_size
,
438 WSANETWORKEVENTS wsa_events
;
439 char *send_last
, *recv_last
, *send_p
, *recv_p
;
440 long mask
= FD_READ
| FD_WRITE
| FD_CLOSE
;
442 trace ( "event_client (%x): starting\n", id
);
443 client_start ( par
);
444 trace ( "event_client (%x): server ready\n", id
);
446 mem
= TlsGetValue ( tls
);
448 /* Prepare event notification for connect, makes socket nonblocking */
449 event
= WSACreateEvent ();
450 WSAEventSelect ( mem
->s
, event
, FD_CONNECT
);
451 tmp
= connect ( mem
->s
, (struct sockaddr
*) &mem
->addr
, sizeof ( mem
->addr
) );
452 if ( tmp
!= 0 && ( err
= WSAGetLastError () ) != WSAEWOULDBLOCK
)
453 ok ( 0, "event_client (%x): connect error: %d\n", id
, err
);
455 tmp
= WaitForSingleObject ( event
, INFINITE
);
456 ok ( tmp
== WAIT_OBJECT_0
, "event_client (%x): wait for connect event failed: %d\n", id
, tmp
);
457 err
= WSAEnumNetworkEvents ( mem
->s
, event
, &wsa_events
);
458 wsa_ok ( err
, 0 ==, "event_client (%lx): WSAEnumNetworkEvents error: %d\n" );
460 err
= wsa_events
.iErrorCode
[ FD_CONNECT_BIT
];
461 ok ( err
== 0, "event_client (%x): connect error: %d\n", id
, err
);
464 trace ( "event_client (%x) connected\n", id
);
466 WSAEventSelect ( mem
->s
, event
, mask
);
468 recv_p
= mem
->recv_buf
;
469 recv_last
= mem
->recv_buf
+ n_expected
;
470 send_p
= mem
->send_buf
;
471 send_last
= mem
->send_buf
+ n_expected
;
475 err
= WaitForSingleObject ( event
, INFINITE
);
476 ok ( err
== WAIT_OBJECT_0
, "event_client (%x): wait failed\n", id
);
478 err
= WSAEnumNetworkEvents ( mem
->s
, event
, &wsa_events
);
479 wsa_ok ( err
, 0 ==, "event_client (%lx): WSAEnumNetworkEvents error: %d\n" );
481 if ( wsa_events
.lNetworkEvents
& FD_WRITE
)
483 err
= wsa_events
.iErrorCode
[ FD_WRITE_BIT
];
484 ok ( err
== 0, "event_client (%x): FD_WRITE error code: %d\n", id
, err
);
489 n
= send ( mem
->s
, send_p
, min ( send_last
- send_p
, par
->buflen
), 0 );
492 err
= WSAGetLastError ();
493 ok ( err
== WSAEWOULDBLOCK
, "event_client (%x): send error: %d\n", id
, err
);
498 while ( n
>= 0 && send_p
< send_last
);
500 if ( send_p
== send_last
)
502 trace ( "event_client (%x): all data sent - shutdown\n", id
);
503 shutdown ( mem
->s
, SD_SEND
);
505 WSAEventSelect ( mem
->s
, event
, mask
);
508 if ( wsa_events
.lNetworkEvents
& FD_READ
)
510 err
= wsa_events
.iErrorCode
[ FD_READ_BIT
];
511 ok ( err
== 0, "event_client (%x): FD_READ error code: %d\n", id
, err
);
512 if ( err
!= 0 ) break;
514 /* First read must succeed */
515 n
= recv ( mem
->s
, recv_p
, min ( recv_last
- recv_p
, par
->buflen
), 0 );
516 wsa_ok ( n
, 0 <=, "event_client (%lx): recv error: %d\n" );
520 if ( recv_p
== recv_last
)
523 trace ( "event_client (%x): all data received\n", id
);
524 WSAEventSelect ( mem
->s
, event
, mask
);
527 n
= recv ( mem
->s
, recv_p
, min ( recv_last
- recv_p
, par
->buflen
), 0 );
528 if ( n
< 0 && ( err
= WSAGetLastError()) != WSAEWOULDBLOCK
)
529 ok ( 0, "event_client (%x): read error: %d\n", id
, err
);
533 if ( wsa_events
.lNetworkEvents
& FD_CLOSE
)
535 trace ( "event_client (%x): close event\n", id
);
536 err
= wsa_events
.iErrorCode
[ FD_CLOSE_BIT
];
537 ok ( err
== 0, "event_client (%x): FD_CLOSE error code: %d\n", id
, err
);
542 ok ( send_p
== send_last
,
543 "simple_client (%x): sent less data than expected: %d of %d\n",
544 id
, send_p
- mem
->send_buf
, n_expected
);
545 ok ( recv_p
== recv_last
,
546 "simple_client (%x): received less data than expected: %d of %d\n",
547 id
, recv_p
- mem
->recv_buf
, n_expected
);
548 recv_p
= test_buffer ( mem
->recv_buf
, gen
->chunk_size
, gen
->n_chunks
);
549 ok ( recv_p
== NULL
, "event_client (%x): test pattern error: %d\n", id
, recv_p
- mem
->recv_buf
);
552 WSACloseEvent ( event
);
553 trace ( "event_client (%x) exiting\n", id
);
557 /**************** Main program utility functions ***************/
559 static void Init (void)
561 WORD ver
= MAKEWORD (2, 2);
564 ok ( WSAStartup ( ver
, &data
) == 0, "WSAStartup failed\n" );
568 static void Exit (void)
571 ok ( WSACleanup() == 0, "WSACleanup failed\n" );
574 static void StartServer (LPTHREAD_START_ROUTINE routine
,
575 test_params
*general
, server_params
*par
)
577 par
->general
= general
;
578 thread
[0] = CreateThread ( NULL
, 0, routine
, par
, 0, &thread_id
[0] );
579 ok ( thread
[0] != NULL
, "Failed to create server thread\n" );
582 static void StartClients (LPTHREAD_START_ROUTINE routine
,
583 test_params
*general
, client_params
*par
)
586 par
->general
= general
;
587 for ( i
= 1; i
<= min ( general
->n_clients
, MAX_CLIENTS
); i
++ )
590 thread
[i
] = CreateThread ( NULL
, 0, routine
, par
, 0, &thread_id
[i
] );
591 ok ( thread
[i
] != NULL
, "Failed to create client thread\n" );
592 /* Make sure the client is up and running */
593 WaitForSingleObject ( client_ready
[client_id
], INFINITE
);
597 static void do_test( test_setup
*test
)
599 DWORD i
, n
= min (test
->general
.n_clients
, MAX_CLIENTS
);
602 server_ready
= CreateEventA ( NULL
, TRUE
, FALSE
, NULL
);
603 for (i
= 0; i
<= n
; i
++)
604 client_ready
[i
] = CreateEventA ( NULL
, TRUE
, FALSE
, NULL
);
606 StartServer ( test
->srv
, &test
->general
, &test
->srv_params
);
607 StartClients ( test
->clt
, &test
->general
, &test
->clt_params
);
608 WaitForSingleObject ( server_ready
, INFINITE
);
610 wait
= WaitForMultipleObjects ( 1 + n
, thread
, TRUE
, 1000 * TEST_TIMEOUT
);
611 ok ( wait
>= WAIT_OBJECT_0
&& wait
<= WAIT_OBJECT_0
+ n
,
612 "some threads have not completed: %lx\n", wait
);
614 if ( ! ( wait
>= WAIT_OBJECT_0
&& wait
<= WAIT_OBJECT_0
+ n
) )
616 for (i
= 0; i
<= n
; i
++)
618 trace ("terminating thread %08lx\n", thread_id
[i
]);
619 if ( WaitForSingleObject ( thread
[i
], 0 ) != WAIT_OBJECT_0
)
620 TerminateThread ( thread
[i
], 0 );
623 CloseHandle ( server_ready
);
624 for (i
= 0; i
<= n
; i
++)
625 CloseHandle ( client_ready
[i
] );
628 static void test_so_reuseaddr()
630 struct sockaddr_in saddr
;
634 saddr
.sin_family
= AF_INET
;
635 saddr
.sin_port
= htons(9375);
636 saddr
.sin_addr
.s_addr
= inet_addr("127.0.0.1");
638 s1
=socket(AF_INET
, SOCK_STREAM
, 0);
639 ok(s1
!=INVALID_SOCKET
, "socket() failed error: %d\n", WSAGetLastError());
640 rc
= bind(s1
, (struct sockaddr
*)&saddr
, sizeof(saddr
));
641 ok(rc
!=SOCKET_ERROR
, "bind(s1) failed error: %d\n", WSAGetLastError());
643 s2
=socket(AF_INET
, SOCK_STREAM
, 0);
644 ok(s2
!=INVALID_SOCKET
, "socket() failed error: %d\n", WSAGetLastError());
648 rc
=getsockopt(s2
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&reuse
, &size
);
649 ok(rc
==0 && reuse
==0,"wrong result in getsockopt(SO_REUSEADDR): rc=%d reuse=%d\n",rc
,reuse
);
651 rc
= bind(s2
, (struct sockaddr
*)&saddr
, sizeof(saddr
));
652 ok(rc
==SOCKET_ERROR
, "bind() succeeded\n");
655 rc
= setsockopt(s2
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&reuse
, sizeof(reuse
));
656 ok(rc
==0, "setsockopt() failed error: %d\n", WSAGetLastError());
659 rc
= bind(s2
, (struct sockaddr
*)&saddr
, sizeof(saddr
));
660 ok(rc
==0, "bind() failed error: %d\n", WSAGetLastError());
667 /************* Array containing the tests to run **********/
669 #define STD_STREAM_SOCKET \
675 static test_setup tests
[NUM_TESTS
] =
677 /* Test 0: synchronous client and server */
698 /* Test 1: event-driven client, synchronous server */
721 /**************** Main program ***************/
730 for (i
= 0; i
< NUM_TESTS
; i
++)
732 trace ( " **** STARTING TEST %d **** \n", i
);
733 do_test ( &tests
[i
] );
734 trace ( " **** TEST %d COMPLETE **** \n", i
);