version 1.3, 2005/03/16 14:11:26
|
version 1.4, 2005/03/16 14:30:36
|
|
|
static sock_info* GetClientSockInfo( server_memory* servMem, SOCKET sockToFind ) | static sock_info* GetClientSockInfo( server_memory* servMem, SOCKET sockToFind ) |
{ | { |
| |
// Looping through all the possible clients |
/* Looping through all the possible clients */ |
int clientNum; | int clientNum; |
for( clientNum = 0; clientNum < MAX_CLIENTS; clientNum++ ){ | for( clientNum = 0; clientNum < MAX_CLIENTS; clientNum++ ){ |
| |
// When the match is found, return the pointer to that sock_info struct |
/* When the match is found, return the pointer to that sock_info struct */ |
if( servMem->sock[clientNum].s == sockToFind ){ | if( servMem->sock[clientNum].s == sockToFind ){ |
| |
return &(servMem->sock[clientNum]); | return &(servMem->sock[clientNum]); |
|
|
| |
} | } |
| |
// Did not find a match. |
/* Did not find a match. */ |
return NULL; | return NULL; |
| |
} | } |
|
|
static sock_info* GetNextOpenSock( server_memory* servMem ) | static sock_info* GetNextOpenSock( server_memory* servMem ) |
{ | { |
| |
// Loop through sock array of servMem |
/* Loop through sock array of servMem */ |
int clientNum; | int clientNum; |
for( clientNum = 0; clientNum < MAX_CLIENTS; clientNum++ ){ | for( clientNum = 0; clientNum < MAX_CLIENTS; clientNum++ ){ |
| |
// when an open slot is found, return |
/* when an open slot is found, return */ |
if( servMem->sock[clientNum].s == INVALID_SOCKET ) | if( servMem->sock[clientNum].s == INVALID_SOCKET ) |
return &(servMem->sock[clientNum]); | return &(servMem->sock[clientNum]); |
| |
} | } |
| |
// When there is no more open socket, return NULL |
/* When there is no more open socket, return NULL */ |
return NULL; | return NULL; |
| |
} | } |
|
|
static BOOL noOpenSock( server_memory* servMem ) | static BOOL noOpenSock( server_memory* servMem ) |
{ | { |
| |
// Loop through sock array of servMem |
/* Loop through sock array of servMem */ |
int clientNum; | int clientNum; |
for( clientNum = 0; clientNum < MAX_CLIENTS; clientNum++ ){ | for( clientNum = 0; clientNum < MAX_CLIENTS; clientNum++ ){ |
| |
// if any socket != INVALID_SOCKET, there is an open socket |
/* if any socket != INVALID_SOCKET, there is an open socket */ |
if( servMem->sock[clientNum].s != INVALID_SOCKET ) | if( servMem->sock[clientNum].s != INVALID_SOCKET ) |
return FALSE; | return FALSE; |
| |
} | } |
| |
// no open sockets |
/* no open sockets */ |
return TRUE; | return TRUE; |
| |
} | } |
|
|
int n_sent = 0, sendLen, err; | int n_sent = 0, sendLen, err; |
int id = GetCurrentThreadId(); | int id = GetCurrentThreadId(); |
| |
// send any data that hasn't been sent yet |
/* send any data that hasn't been sent yet */ |
while( sockInfo->nsent < sockInfo->nread ){ | while( sockInfo->nsent < sockInfo->nread ){ |
| |
// find out the buffer length to send |
/* find out the buffer length to send */ |
sendLen = min( sockInfo->nread - sockInfo->nsent, servBufLen ); | sendLen = min( sockInfo->nread - sockInfo->nsent, servBufLen ); |
| |
// send the data |
/* send the data */ |
n_sent = send( sockInfo->s, sockInfo->buf + sockInfo->nsent, sendLen, 0 ); | n_sent = send( sockInfo->s, sockInfo->buf + sockInfo->nsent, sendLen, 0 ); |
| |
// If there was an error, break |
/* If there was an error, break */ |
if( n_sent == SOCKET_ERROR ) | if( n_sent == SOCKET_ERROR ) |
break; | break; |
| |
// update the number bytes sent |
/* update the number bytes sent */ |
sockInfo->nsent += n_sent; | sockInfo->nsent += n_sent; |
| |
} | } |
| |
// check the error |
/* check the error */ |
if( n_sent == SOCKET_ERROR && ( err = WSAGetLastError () ) != WSAEWOULDBLOCK ) | if( n_sent == SOCKET_ERROR && ( err = WSAGetLastError () ) != WSAEWOULDBLOCK ) |
ok( 0, "async_server (%x): send error: %d\n", id, err ); | ok( 0, "async_server (%x): send error: %d\n", id, err ); |
| |
|
|
| |
trace( "async_server (%x): accept event\n", id ); | trace( "async_server (%x): accept event\n", id ); |
| |
// Find the next available socket |
/* Find the next available socket */ |
sockInfo = GetNextOpenSock( mem ); | sockInfo = GetNextOpenSock( mem ); |
ok( sockInfo != NULL, "async_server (%x): no more open socket\n", id ); | ok( sockInfo != NULL, "async_server (%x): no more open socket\n", id ); |
| |
// accept connection |
/* accept connection */ |
sockInfo->s = accept( mem->s, (struct sockaddr*) &peer, &addrLen ); | sockInfo->s = accept( mem->s, (struct sockaddr*) &peer, &addrLen ); |
wsa_ok( sockInfo->s, INVALID_SOCKET !=, "async_server (%lx): accept failed: %d\n" ); | wsa_ok( sockInfo->s, INVALID_SOCKET !=, "async_server (%lx): accept failed: %d\n" ); |
| |
// check the address retrieved from accept() is valid |
/* check the address retrieved from accept() is valid */ |
ok( peer.sin_addr.s_addr == inet_addr( inetAddr ), "async_server (%x): strange peer address\n", id ); | ok( peer.sin_addr.s_addr == inet_addr( inetAddr ), "async_server (%x): strange peer address\n", id ); |
| |
// make this newly accepted socket asynchronous |
/* make this newly accepted socket asynchronous */ |
err = WSAAsyncSelect( sockInfo->s, async_params.hwnd, ASYNC_EVENT, FD_ACCEPT | FD_READ | FD_WRITE | FD_CLOSE ); | err = WSAAsyncSelect( sockInfo->s, async_params.hwnd, ASYNC_EVENT, FD_ACCEPT | FD_READ | FD_WRITE | FD_CLOSE ); |
wsa_ok( err, SOCKET_ERROR !=, "async_server (%lx): WSAAsyncSelect failed: %d\n" ); | wsa_ok( err, SOCKET_ERROR !=, "async_server (%lx): WSAAsyncSelect failed: %d\n" ); |
| |
|
|
| |
case FD_WRITE: | case FD_WRITE: |
| |
// get the sock_info* of this client socket |
/* get the sock_info* of this client socket */ |
sockInfo = GetClientSockInfo( mem, clientSock ); | sockInfo = GetClientSockInfo( mem, clientSock ); |
ok( sockInfo != NULL, "async_server (%x): socket to write to is not open\n", id ); | ok( sockInfo != NULL, "async_server (%x): socket to write to is not open\n", id ); |
| |
// try sending any remaining data |
/* try sending any remaining data */ |
try_send_all_buf( sockInfo, servBufLen ); | try_send_all_buf( sockInfo, servBufLen ); |
break; | break; |
| |
case FD_READ: | case FD_READ: |
| |
// get the sock_info* of this client socket |
/* get the sock_info* of this client socket */ |
sockInfo = GetClientSockInfo( mem, clientSock ); | sockInfo = GetClientSockInfo( mem, clientSock ); |
ok( sockInfo != NULL, "async_server (%x): socket to read from is not open\n", id ); | ok( sockInfo != NULL, "async_server (%x): socket to read from is not open\n", id ); |
| |
// retrieve the data |
/* retrieve the data */ |
n_recvd = recv( sockInfo->s, sockInfo->buf + sockInfo->nread, servBufLen, 0 ); | n_recvd = recv( sockInfo->s, sockInfo->buf + sockInfo->nread, servBufLen, 0 ); |
if( n_recvd == SOCKET_ERROR && ( err = WSAGetLastError () ) != WSAEWOULDBLOCK ) | if( n_recvd == SOCKET_ERROR && ( err = WSAGetLastError () ) != WSAEWOULDBLOCK ) |
ok( 0, "async_server (%x): recv error: %d\n", id, err ); | ok( 0, "async_server (%x): recv error: %d\n", id, err ); |
| |
// record number of bytes read so far |
/* record number of bytes read so far */ |
if( n_recvd != SOCKET_ERROR ) | if( n_recvd != SOCKET_ERROR ) |
sockInfo->nread += n_recvd; | sockInfo->nread += n_recvd; |
| |
// send the remaining data |
/* send the remaining data */ |
try_send_all_buf( sockInfo, servBufLen ); | try_send_all_buf( sockInfo, servBufLen ); |
break; | break; |
| |
case FD_CLOSE: | case FD_CLOSE: |
| |
// Client closed connection - close the connection with this server. |
/* Client closed connection - close the connection with this server. */ |
trace( "async_server (%x): close event\n", id ); | trace( "async_server (%x): close event\n", id ); |
sockInfo = GetClientSockInfo( mem, clientSock ); | sockInfo = GetClientSockInfo( mem, clientSock ); |
ok( sockInfo != NULL, "async_server (%x): socket to close is not open\n", id ); | ok( sockInfo != NULL, "async_server (%x): socket to close is not open\n", id ); |
| |
// Check the data it received |
/* Check the data it received */ |
n_expected = gen->n_chunks * gen->chunk_size; | n_expected = gen->n_chunks * gen->chunk_size; |
ok( sockInfo->nread == n_expected, | ok( sockInfo->nread == n_expected, |
"async_server (%x): received less data than expected: %d of %d\n", id, sockInfo->nread, n_expected ); | "async_server (%x): received less data than expected: %d of %d\n", id, sockInfo->nread, n_expected ); |
|
|
p = test_buffer( sockInfo->buf, gen->chunk_size, gen->n_chunks ); | p = test_buffer( sockInfo->buf, gen->chunk_size, gen->n_chunks ); |
ok( p == NULL, "async_server (%x): test pattern error: %d\n", id, p - sockInfo->buf); | ok( p == NULL, "async_server (%x): test pattern error: %d\n", id, p - sockInfo->buf); |
| |
// clean up |
/* clean up */ |
wsa_ok( closesocket( sockInfo->s ), 0 ==, "async_server (%lx): closesocket error: %d\n" ); | wsa_ok( closesocket( sockInfo->s ), 0 ==, "async_server (%lx): closesocket error: %d\n" ); |
sockInfo->s = INVALID_SOCKET; | sockInfo->s = INVALID_SOCKET; |
| |
// If all sockets are closed, kill the server |
/* If all sockets are closed, kill the server */ |
if( noOpenSock( mem ) ){ | if( noOpenSock( mem ) ){ |
| |
trace( "async_server (%x) exiting\n", id ); | trace( "async_server (%x) exiting\n", id ); |
|
|
set_so_opentype( FALSE ); /* non-overlapped */ | set_so_opentype( FALSE ); /* non-overlapped */ |
server_start( par ); | server_start( par ); |
| |
// set up async_params structure |
/* set up async_params structure */ |
memset( &async_params, 0, sizeof( async_params ) ); | memset( &async_params, 0, sizeof( async_params ) ); |
async_params.svc_params = par; | async_params.svc_params = par; |
async_params.mem = TlsGetValue( tls ); | async_params.mem = TlsGetValue( tls ); |
| |
// Listen to socket |
|
wsa_ok( listen ( (async_params.mem)->s, SOMAXCONN ), 0 ==, "async_server (%lx): listen failed: %d\n"); | wsa_ok( listen ( (async_params.mem)->s, SOMAXCONN ), 0 ==, "async_server (%lx): listen failed: %d\n"); |
| |
// Get the current instance |
/* Get the current instance */ |
HINSTANCE instance = GetModuleHandle( NULL ); | HINSTANCE instance = GetModuleHandle( NULL ); |
ok( instance != NULL, "async_server (%x):GetModuleHandle error %ld\n", id, GetLastError() ); | ok( instance != NULL, "async_server (%x):GetModuleHandle error %ld\n", id, GetLastError() ); |
| |
// Create a hiddent window to handle async events |
/* Create a hiddent window to handle async events */ |
WNDCLASS windowClass; | WNDCLASS windowClass; |
windowClass.lpszClassName = "Hidden_Winsock_Window"; | windowClass.lpszClassName = "Hidden_Winsock_Window"; |
windowClass.style = CS_HREDRAW | CS_VREDRAW; | windowClass.style = CS_HREDRAW | CS_VREDRAW; |
|
|
ok( retVal != -1, "async_server (%x): GetMessage error %ld\n", id, GetLastError() ); | ok( retVal != -1, "async_server (%x): GetMessage error %ld\n", id, GetLastError() ); |
if( retVal == -1 ){ | if( retVal == -1 ){ |
| |
// exit so that the server won't block |
/* exit so that the server won't block */ |
trace( "async_server (%x): exiting\n", id ); | trace( "async_server (%x): exiting\n", id ); |
server_stop(); | server_stop(); |
| |
} | } |
| |
// Translate and dispatch the message |
/* Translate and dispatch the message */ |
TranslateMessage( &msg ); | TranslateMessage( &msg ); |
DispatchMessage( &msg ); | DispatchMessage( &msg ); |
| |