📄 sock.c
字号:
ok ( mem->sock[0].peer.sin_addr.s_addr == inet_addr ( gen->inet_addr ), "simple_server (%x): strange peer address", id ); /* Receive data & check it */ n_recvd = do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, n_expected, par->buflen ); ok ( n_recvd == n_expected, "simple_server (%x): received less data then expected: %d of %d", id, n_recvd, n_expected ); p = test_buffer ( mem->sock[0].buf, gen->chunk_size, gen->n_chunks ); ok ( p == NULL, "simple_server (%x): test pattern error: %d", id, p - mem->sock[0].buf); /* Echo data back */ n_sent = do_synchronous_send ( mem->sock[0].s, mem->sock[0].buf, n_expected, par->buflen ); ok ( n_sent == n_expected, "simple_server (%x): sent less data then expected: %d of %d", id, n_sent, n_expected ); /* cleanup */ read_zero_bytes ( mem->sock[0].s ); wsa_ok ( closesocket ( mem->sock[0].s ), 0 ==, "simple_server (%lx): closesocket error: %d" ); mem->sock[0].s = INVALID_SOCKET; } trace ( "simple_server (%x) exiting\n", id ); server_stop ();}/**************** Clients ***************//* * simple_client: A very basic client doing synchronous IO. */static VOID WINAPI simple_client ( client_params *par ){ test_params *gen = par->general; client_memory *mem; int n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, id; char *p; id = GetCurrentThreadId(); trace ( "simple_client (%x): starting\n", id ); /* wait here because we want to call set_so_opentype before creating a socket */ WaitForSingleObject ( server_ready, INFINITE ); trace ( "simple_client (%x): server ready\n", id ); check_so_opentype (); set_so_opentype ( FALSE ); /* non-overlapped */ client_start ( par ); mem = TlsGetValue ( tls ); /* Connect */ wsa_ok ( connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ), 0 ==, "simple_client (%lx): connect error: %d" ); ok ( set_blocking ( mem->s, TRUE ) == 0, "simple_client (%x): failed to set blocking mode", id ); trace ( "simple_client (%x) connected\n", id ); /* send data to server */ n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, par->buflen ); ok ( n_sent == n_expected, "simple_client (%x): sent less data then expected: %d of %d", id, n_sent, n_expected ); /* shutdown send direction */ wsa_ok ( shutdown ( mem->s, SD_SEND ), 0 ==, "simple_client (%lx): shutdown failed: %d" ); /* Receive data echoed back & check it */ n_recvd = do_synchronous_recv ( mem->s, mem->recv_buf, n_expected, par->buflen ); ok ( n_recvd == n_expected, "simple_client (%x): received less data then expected: %d of %d", id, n_recvd, n_expected ); /* check data */ p = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks ); ok ( p == NULL, "simple_client (%x): test pattern error: %d", id, p - mem->recv_buf); /* cleanup */ read_zero_bytes ( mem->s ); trace ( "simple_client (%x) exiting\n", id ); client_stop ();}/* * event_client: An event-driven client */static void WINAPI event_client ( client_params *par ){ test_params *gen = par->general; client_memory *mem; int id = GetCurrentThreadId(), n_expected = gen->n_chunks * gen->chunk_size, tmp, err, n; HANDLE event; WSANETWORKEVENTS wsa_events; char *send_last, *recv_last, *send_p, *recv_p; long mask = FD_READ | FD_WRITE | FD_CLOSE; trace ( "event_client (%x): starting\n", id ); client_start ( par ); trace ( "event_client (%x): server ready\n", id ); mem = TlsGetValue ( tls ); /* Prepare event notification for connect, makes socket nonblocking */ event = WSACreateEvent (); WSAEventSelect ( mem->s, event, FD_CONNECT ); tmp = connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ); if ( tmp != 0 && ( err = WSAGetLastError () ) != WSAEWOULDBLOCK ) ok ( 0, "event_client (%x): connect error: %d", id, err ); tmp = WaitForSingleObject ( event, INFINITE ); ok ( tmp == WAIT_OBJECT_0, "event_client (%x): wait for connect event failed: %d", id, tmp ); err = WSAEnumNetworkEvents ( mem->s, event, &wsa_events ); wsa_ok ( err, 0 ==, "event_client (%lx): WSAEnumNetworkEvents error: %d\n" ); err = wsa_events.iErrorCode[ FD_CONNECT_BIT ]; ok ( err == 0, "event_client (%x): connect error: %d", id, err ); if ( err ) goto out; trace ( "event_client (%x) connected\n", id ); WSAEventSelect ( mem->s, event, mask ); recv_p = mem->recv_buf; recv_last = mem->recv_buf + n_expected; send_p = mem->send_buf; send_last = mem->send_buf + n_expected; while ( TRUE ) { err = WaitForSingleObject ( event, INFINITE ); ok ( err == WAIT_OBJECT_0, "event_client (%x): wait failed", id ); err = WSAEnumNetworkEvents ( mem->s, event, &wsa_events ); wsa_ok ( err, 0 ==, "event_client (%lx): WSAEnumNetworkEvents error: %d\n" ); if ( wsa_events.lNetworkEvents & FD_WRITE ) { err = wsa_events.iErrorCode[ FD_WRITE_BIT ]; ok ( err == 0, "event_client (%x): FD_WRITE error code: %d\n", id, err ); if ( err== 0 ) do { n = send ( mem->s, send_p, min ( send_last - send_p, par->buflen ), 0 ); if ( n < 0 ) { err = WSAGetLastError (); ok ( err == WSAEWOULDBLOCK, "event_client (%x): send error: %d\n", id, err ); } else send_p += n; } while ( n >= 0 && send_p < send_last ); if ( send_p == send_last ) { trace ( "event_client (%x): all data sent - shutdown\n", id ); shutdown ( mem->s, SD_SEND ); mask &= ~FD_WRITE; WSAEventSelect ( mem->s, event, mask ); } } if ( wsa_events.lNetworkEvents & FD_READ ) { err = wsa_events.iErrorCode[ FD_READ_BIT ]; ok ( err == 0, "event_client (%x): FD_READ error code: %d\n", id, err ); if ( err != 0 ) break; /* First read must succeed */ n = recv ( mem->s, recv_p, min ( recv_last - recv_p, par->buflen ), 0 ); wsa_ok ( n, 0 <=, "event_client (%lx): recv error: %d\n" ); while ( n >= 0 ) { recv_p += n; if ( recv_p == recv_last ) { mask &= ~FD_READ; trace ( "event_client (%x): all data received\n", id ); WSAEventSelect ( mem->s, event, mask ); break; } n = recv ( mem->s, recv_p, min ( recv_last - recv_p, par->buflen ), 0 ); if ( n < 0 && ( err = WSAGetLastError()) != WSAEWOULDBLOCK ) ok ( 0, "event_client (%x): read error: %d\n", id, err ); } } if ( wsa_events.lNetworkEvents & FD_CLOSE ) { trace ( "event_client (%x): close event\n", id ); err = wsa_events.iErrorCode[ FD_CLOSE_BIT ]; ok ( err == 0, "event_client (%x): FD_CLOSE error code: %d\n", id, err ); break; } } ok ( send_p == send_last, "simple_client (%x): sent less data then expected: %d of %d", id, send_p - mem->send_buf, n_expected ); ok ( recv_p == recv_last, "simple_client (%x): received less data then expected: %d of %d", id, recv_p - mem->recv_buf, n_expected ); recv_p = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks ); ok ( recv_p == NULL, "event_client (%x): test pattern error: %d", id, recv_p - mem->recv_buf);out: WSACloseEvent ( event ); trace ( "event_client (%x) exiting\n", id ); client_stop ();}/**************** Main program utility functions ***************/static void Init (void){ WORD ver = MAKEWORD (2, 2); WSADATA data; ok ( WSAStartup ( ver, &data ) == 0, "WSAStartup failed" ); tls = TlsAlloc();}static void Exit (void){ TlsFree ( tls ); ok ( WSACleanup() == 0, "WSACleanup failed" );}static void StartServer (LPTHREAD_START_ROUTINE routine, test_params *general, server_params *par){ par->general = general; thread[0] = CreateThread ( NULL, 0, routine, par, 0, &thread_id[0] ); ok ( thread[0] != NULL, "Failed to create server thread" );}static void StartClients (LPTHREAD_START_ROUTINE routine, test_params *general, client_params *par){ int i; par->general = general; for ( i = 1; i <= min ( general->n_clients, MAX_CLIENTS ); i++ ) { client_id = i - 1; thread[i] = CreateThread ( NULL, 0, routine, par, 0, &thread_id[i] ); ok ( thread[i] != NULL, "Failed to create client thread" ); /* Make sure the client is up and running */ WaitForSingleObject ( client_ready[client_id], INFINITE ); };}static void do_test( test_setup *test ){ DWORD i, n = min (test->general.n_clients, MAX_CLIENTS); DWORD wait; server_ready = CreateEventA ( NULL, TRUE, FALSE, NULL ); for (i = 0; i <= n; i++) client_ready[i] = CreateEventA ( NULL, TRUE, FALSE, NULL ); StartServer ( test->srv, &test->general, &test->srv_params ); StartClients ( test->clt, &test->general, &test->clt_params ); WaitForSingleObject ( server_ready, INFINITE ); wait = WaitForMultipleObjects ( 1 + n, thread, TRUE, 1000 * TEST_TIMEOUT ); ok ( wait >= WAIT_OBJECT_0 && wait <= WAIT_OBJECT_0 + n , "some threads have not completed: %lx\n", wait ); if ( ! ( wait >= WAIT_OBJECT_0 && wait <= WAIT_OBJECT_0 + n ) ) { for (i = 0; i <= n; i++) { trace ("terminating thread %08lx\n", thread_id[i]); if ( WaitForSingleObject ( thread[i], 0 ) != WAIT_OBJECT_0 ) TerminateThread ( thread [i], 0 ); } } CloseHandle ( server_ready ); for (i = 0; i <= n; i++) CloseHandle ( client_ready[i] );}/************* Array containing the tests to run **********/#define STD_STREAM_SOCKET \ SOCK_STREAM, \ 0, \ "127.0.0.1", \ 9374static test_setup tests [NUM_TESTS] ={ /* Test 0: synchronous client and server */ { { STD_STREAM_SOCKET, 2048, 16, 2 }, simple_server, { NULL, 0, 64 }, simple_client, { NULL, 0, 128 } }, /* Test 1: event-driven client, synchronous server */ { { STD_STREAM_SOCKET, 2048, 16, 2 }, simple_server, { NULL, 0, 64 }, event_client, { NULL, WSA_FLAG_OVERLAPPED, 128 } }};/**************** Main program ***************/START_TEST( sock ){ int i; Init(); for (i = 0; i < NUM_TESTS; i++) { trace ( " **** STARTING TEST %d **** \n", i ); do_test ( &tests[i] ); trace ( " **** TEST %d COMPLETE **** \n", i ); } Exit();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -