(file) Return to WineWinsockAsyncTest.c CVS log (file) (dir) Up to [RizwankCVS] / wine1 / wine

  1 cs130_ryutaro 1.1 #include <stdio.h>
  2                   #include "winsock2.h"
  3                   #include "windows.h"
  4                   
  5 cs130_ryutaro 1.2 #include <wine/test.h>
  6                   #include <winbase.h>
  7                   
  8 cs130_ryutaro 1.1 /* The #pragma directives offer a way for each compiler to offer machine- 
  9                   	and operating-system-specific features while retaining overall 
 10                   	compatibility with the C and C++ languages.
 11                   	The next line places a library-search record, ws2_32, in the object file. */
 12 cs130_ryutaro 1.2 //  #pragma comment ( lib, "ws2_32" )
 13 cs130_ryutaro 1.1 
 14                   /* constants */
 15                   #define ASYNC_EVENT (WM_USER +5)     // the message we'll use for our async notification
 16                   #define PORT_NUM 27015
 17                   #define PACKET_SZ 32
 18                   #define FILE_SZ 100
 19                   #define SERVER_START_TIME 3000
 20                   #define MAX_WAIT_TIME 30000 // 30 seconds expressed in milliseconds
 21                   #define NUM_THREADS_TO_WAIT 2
 22                   
 23                   enum  // define all the exit codes for a thread
 24                   {
 25                   	TH_START_ERROR = 1001,
 26                   	TH_SOCKET_ERROR,
 27                   	TH_SOCKADDR_ERROR,
 28                   	TH_BIND_ERROR,
 29                   	TH_CONNECT_ERROR,
 30                   	TH_LISTEN_ERROR,
 31                   	TH_ACCEPT_ERROR,
 32                   	TH_SELECT_ERROR,
 33                   	TH_RECV_ERROR,
 34 cs130_ryutaro 1.1 	TH_SEND_ERROR,
 35                   	TH_WINDOW_ERROR,
 36                   	TH_MSG_ERROR
 37                   
 38                   } ThreadExitCodes;
 39                   
 40                   /* static func prototypes */
 41                   static int WSAStartup_w( WORD wVersionRequired, LPWSADATA lpWSAData );
 42                   static SOCKET socket_w( int af, int type, int protocol );
 43                   static LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 44                   static HWND WineCreateWindow( HINSTANCE hInstance);
 45                   static void WineThreadCleanUp();
 46                   static void WineCreateFile();
 47                   static DWORD WINAPI WineRunServer();
 48                   static DWORD WINAPI WineRunClient();
 49 cs130_ryutaro 1.3 
 50 cs130_ryutaro 1.1 /* struct def */
 51                   typedef struct 
 52                   {
 53                   	DWORD id;
 54                   	HANDLE handle;
 55                   	int bytesRecvd;
 56                   	int bytesSent;
 57                   	char packet[PACKET_SZ];
 58                   } thread_t;
 59                   
 60                   /* global vars */
 61                   static char FileBuf[FILE_SZ];
 62                   static thread_t ServerThread;
 63                   static thread_t ClientThread;
 64                   
 65                   /* 
 66                   Wrapper for WSAStartup(). 
 67                   The WSAStartup function must be the first Windows Sockets function 
 68                   called by an application or DLL. It allows an application or DLL to 
 69                   specify the version of Windows Sockets required and retrieve details 
 70                   of the specific Windows Sockets implementation. 
 71 cs130_ryutaro 1.1 
 72                   Paremeters:
 73                   wVersionRequested 
 74                   	[in] Highest version of Windows Sockets support that the caller can use. 
 75                   		The high-order byte specifies the minor version (revision) number; 
 76                   		the low-order byte specifies the major version number. 
 77                   lpWSAData 
 78                   	[out] Pointer to the WSADATA data structure that is to receive details of 
 79                   		the Windows Sockets implementation. 
 80                   
 81                   Error code          |        Meaning 
 82                   WSASYSNOTREADY      | Indicates that the underlying network subsystem is 
 83                   						not ready for network communication. 
 84                   WSAVERNOTSUPPORTED  | The version of Windows Sockets support requested is 
 85                   						not provided by this particular Windows Sockets 
 86                   						implementation. 
 87                   WSAEINPROGRESS      | A blocking Windows Sockets 1.1 operation is in progress. 
 88                   WSAEPROCLIM         | Limit on the number of tasks supported by the Windows 
 89                   						Sockets implementation has been reached. 
 90                   WSAEFAULT           | The lpWSAData is not a valid pointer. 
 91                   */
 92 cs130_ryutaro 1.1 static int WSAStartup_w( WORD wVersionRequired, LPWSADATA lpWSAData )
 93                   {
 94                   	int errCode = 0;
 95                   	
 96                   	// WSAVERNOTSUPPORTED test
 97                   	WSADATA tmpLpWSAData;
 98                   	errCode = WSAStartup( MAKEWORD( 0, 0 ), &tmpLpWSAData );
 99                   	if( errCode != WSAVERNOTSUPPORTED ) {
100                   
101                   		// print out the Error Code to be thorough
102 cs130_ryutaro 1.3 		trace( "WSAVERNOTSUPPORTED test failed with error code: %d\n", errCode );		
103 cs130_ryutaro 1.1 		errCode = 0;
104                   	}
105                   
106                   	// WSEFAULT test
107                   	errCode = WSAStartup( wVersionRequired, ( LPWSADATA ) 0 );
108                   	if( errCode != WSAEFAULT ) {
109                   
110                   		// print out the Error Code to be thorough
111 cs130_ryutaro 1.3 		trace( "WSAFAULT test failed with error code: %d\n", errCode );		
112 cs130_ryutaro 1.1 		errCode = 0;
113                   	}
114                   
115                   	// lastly regular case - should succeed
116                   	errCode = WSAStartup( wVersionRequired, lpWSAData );
117                   	if( errCode != 0 ) {
118                   
119                   		// print out the Error Code to be thorough
120                   		errCode = WSAGetLastError();		
121 cs130_ryutaro 1.3 		trace( "WSAStartup() failed with error code: %d\n", errCode );		
122 cs130_ryutaro 1.1 	}
123                   
124                   	return errCode;
125                   }
126                   
127                   /* 
128                   Wrapper for socket().
129                   socket() function creates a socket that is bound to a specific service provider.
130                   
131                   Parameters:
132                   af
133                   	[in] Address family specification. 
134                   type 
135                   	[in] Type specification for the new socket. Types are:
136                   		SOCK_STREAM - Uses TCP
137                   		SOCK_DGRAM  - Uses UDP 
138                   protocol 
139                   	[in] Protocol to be used with the socket that is specific to the indicated address 
140                   		family. 
141                   
142                   If no error occurs, socket returns a descriptor referencing the new socket. Otherwise, 
143 cs130_ryutaro 1.1 a value of INVALID_SOCKET is returned, and a specific error code can be retrieved by 
144                   calling WSAGetLastError.
145                   
146                   Error code              |        Meaning 
147                   WSANOTINITIALISED       | A successful WSAStartup call must occur before using this function. 
148                   WSAENETDOWN             | The network subsystem or the associated service provider has failed. 
149                   WSAEAFNOSUPPORT         | The specified address family is not supported. 
150                   WSAEINPROGRESS          | A blocking Windows Sockets 1.1 call is in progress, or the service 
151                   							provider is still processing a callback function. 
152                   WSAEMFILE               | No more socket descriptors are available. 
153                   WSAENOBUFS              | No buffer space is available. The socket cannot be created. 
154                   WSAEPROTONOSUPPORT      | The specified protocol is not supported. 
155                   WSAEPROTOTYPE           | The specified protocol is the wrong type for this socket. 
156                   WSAESOCKTNOSUPPORT      | The specified socket type is not supported in this address family. 
157                   
158                   NOTE: WSAEPROTOTYPE  tried to do test for this error by specifying type=SOCK_DGRAM and
159                   	protocol=IPPROTO_TCP but the return error code was WSEPROTONOSUPPORT
160                   */
161                   static SOCKET socket_w( int af, int type, int protocol )
162                   {
163                       // Create a socket.
164 cs130_ryutaro 1.1     SOCKET m_socket;
165                   
166                   	// WSAEAFNOSUPPORT test	
167                   	m_socket = socket( -999, SOCK_STREAM, IPPROTO_TCP );
168                   	if( m_socket != INVALID_SOCKET || WSAGetLastError() != WSAEAFNOSUPPORT ){
169 cs130_ryutaro 1.3 		trace( "WSAEAFNOSUPPORT test failed: %d %d\n", m_socket, WSAGetLastError() );
170 cs130_ryutaro 1.1     }
171                   
172                   	// WSAEPROTONOSUPPORT test
173                   	m_socket = socket( AF_INET, SOCK_STREAM, -999 );
174                   	if( m_socket != INVALID_SOCKET || WSAGetLastError() != WSAEPROTONOSUPPORT ){
175 cs130_ryutaro 1.3 		trace( "WSAEPROTONOSUPPORT test failed: %d %d\n", m_socket, WSAGetLastError() );
176 cs130_ryutaro 1.1 	}
177                   
178                   	// WSAESOCKTNOSUPPORT test
179                   	m_socket = socket( AF_INET, -999, IPPROTO_TCP );
180                   	if( m_socket != INVALID_SOCKET || WSAGetLastError() != WSAESOCKTNOSUPPORT ){
181 cs130_ryutaro 1.3 		trace( "WSAEPROTONOSUPPORT test failed: %d %d\n", m_socket, WSAGetLastError() );
182 cs130_ryutaro 1.1     }
183                   
184                   	m_socket = socket( af, type, protocol );
185                   	if( m_socket == INVALID_SOCKET ){
186 cs130_ryutaro 1.3 		trace( "Error at socket(): %d\n", WSAGetLastError() );
187 cs130_ryutaro 1.1     }
188                   
189                   	return m_socket;
190                   }
191                   
192                   /* 
193                   Call back event handler for asynchronous client 
194                   */
195                   static LRESULT CALLBACK WndProcedure( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
196                   {
197 cs130_ryutaro 1.2     int eventCode = 0; 
198 cs130_ryutaro 1.1     switch( msg )
199                       {
200                           case ASYNC_EVENT: 
201 cs130_ryutaro 1.2 			eventCode = WSAGETSELECTEVENT( lParam );
202 cs130_ryutaro 1.1             SOCKET socket = (SOCKET) wParam;
203                   			SOCKET acceptSock;
204                   			int bytesRecv = 0;
205                   			int i = 0, j = 0;
206                   			char* buf;
207                   			if( GetCurrentThreadId() == ServerThread.id )
208                   				buf = ServerThread.packet;
209                   			else
210                   				buf = ClientThread.packet;
211                   
212                   			switch( eventCode )
213                               {
214                   				case FD_ACCEPT:					
215 cs130_ryutaro 1.2 					trace( "%ld accept called\n", GetCurrentThreadId() );
216 cs130_ryutaro 1.1 					acceptSock = accept( socket, NULL, NULL );
217                   					if( acceptSock == INVALID_SOCKET ){
218 cs130_ryutaro 1.3 						trace( "accept error %d\n", WSAGetLastError() );
219 cs130_ryutaro 1.1 						closesocket( socket );
220                   						ExitThread( TH_ACCEPT_ERROR );
221                   					}
222 cs130_ryutaro 1.2 					trace( "%ld: connection accepted\n", GetCurrentThreadId() );
223 cs130_ryutaro 1.1 					break;
224                   
225                                   case FD_CONNECT:
226                   
227                   					// a call to connect() has completed
228 cs130_ryutaro 1.2 					trace("%ld CONNECTED!\n", GetCurrentThreadId() );
229 cs130_ryutaro 1.1                     break;
230                   
231                   				case FD_CLOSE:				
232                   
233                   					// a connection has been closed					
234                   					closesocket( socket );
235 cs130_ryutaro 1.2 					trace( "%ld: Closed socket\n", GetCurrentThreadId());
236 cs130_ryutaro 1.1 					WSACleanup();
237                   					ExitThread( 0 );
238                   					break;
239                   
240                   				case FD_READ:
241                   
242                   					// WinSock has data waiting to be read									
243                   					bytesRecv = recv( socket, buf, PACKET_SZ, 0 );
244                   
245 cs130_ryutaro 1.2 					trace( "%ld received %d bytes: ", GetCurrentThreadId(), bytesRecv );
246 cs130_ryutaro 1.1 					while( i < PACKET_SZ && buf[i] != (char)EOF ){
247 cs130_ryutaro 1.3 						printf( "%c", buf[i] );
248 cs130_ryutaro 1.1 						i++;
249                   					}
250 cs130_ryutaro 1.3 					printf( "\n" );
251 cs130_ryutaro 1.1 
252                   					// Now send it back if you're the server
253                   					if( GetCurrentThreadId() == ServerThread.id ){
254                   
255                   						if( send( socket, buf, bytesRecv, 0 ) == SOCKET_ERROR ){
256                   
257                   							// check if the network buffer is full and can send no more
258                   					        // data. If so then break from the loop
259                   					        if( WSAGetLastError() == WSAEWOULDBLOCK ){
260 cs130_ryutaro 1.2 						          // break from the loop – buffer is full
261                   								trace( "woud block send!\n" );
262 cs130_ryutaro 1.1 								break;
263                   						    }
264                   							else{ // another error
265 cs130_ryutaro 1.2 								trace(" some send error\n" );
266 cs130_ryutaro 1.1 								return 0;
267                   							}
268                   						}
269                   
270 cs130_ryutaro 1.2 						trace( "%ld sent back %d bytes: ", GetCurrentThreadId(), bytesRecv );
271 cs130_ryutaro 1.1 						j = 0;
272                   						while( j < bytesRecv ){
273 cs130_ryutaro 1.3 							printf( "%c", buf[j] );
274 cs130_ryutaro 1.1 							j++;
275                   						}
276 cs130_ryutaro 1.3 						printf( "\n" );
277 cs130_ryutaro 1.1 
278                   					}
279                   					else{
280                   
281                   						// Client: close the connection when it received back FILE_SZ
282                   						ClientThread.bytesRecvd += bytesRecv;
283                   						if( ClientThread.bytesRecvd >= FILE_SZ ){
284 cs130_ryutaro 1.2 							trace( "%ld closing socket\n", GetCurrentThreadId() );		
285 cs130_ryutaro 1.1 							closesocket( socket );
286                   							WSACleanup();
287                   							ExitThread( 0 );
288                   						}
289                   					}
290                                       break;
291                   
292                   				case FD_WRITE:
293                   
294                   					// don't do anything here for server
295                   					if( GetCurrentThreadId() == ServerThread.id )
296                   						break;
297                   
298                   					// enter an infinite loop
299                   					BOOL notDone = TRUE;
300                   				    while( notDone ){
301                   
302                   						// determine how many bytes to send
303                   						int bytesToSend = 0;
304                   						if( sizeof( FileBuf ) - ClientThread.bytesSent < PACKET_SZ ){
305                   
306 cs130_ryutaro 1.1 							// the bytes remaining to send is smaller than packet size
307                   							bytesToSend = (int) ( sizeof( FileBuf ) - ClientThread.bytesSent );
308                   							notDone = FALSE;
309                   
310                   						}
311                   						else{
312                   
313                   							// the bytes remaining is greater than or equal to PACKET_SZ
314                   							bytesToSend = PACKET_SZ;
315                   
316                   						}
317                   							
318                   						memcpy( buf, FileBuf + ClientThread.bytesSent, bytesToSend ); 
319                   						ClientThread.bytesSent += bytesToSend;
320                   						
321                   						// send the packet off to the Server if it is filled
322                   						if( send( socket, buf, bytesToSend, 0 ) == SOCKET_ERROR ){
323                   
324                   							// check if the network buffer is full and can send no more
325                   					        // data. If so then break from the loop
326                   					        if( WSAGetLastError() == WSAEWOULDBLOCK ){
327 cs130_ryutaro 1.2 						          // break from the loop – buffer is full
328 cs130_ryutaro 1.1 						          break;
329                   						    }
330                   							else{ // another error
331                   								return 0;
332                   							}
333                   						}
334                   						
335 cs130_ryutaro 1.2 						trace( "%ld sent: ", GetCurrentThreadId() );
336 cs130_ryutaro 1.1 						j = 0;
337                   						while( j < PACKET_SZ &&  buf[j] != (char)EOF ){
338 cs130_ryutaro 1.3 							printf( "%c", buf[j] );
339 cs130_ryutaro 1.1 							j++;
340                   						}
341 cs130_ryutaro 1.3 						printf( "\n" );
342 cs130_ryutaro 1.1 					}
343                   					break;
344                               }
345                        }
346                        return DefWindowProc( hWnd, msg, wParam, lParam );
347                   }
348                   
349                   /* 
350                   Creates a hidden window object.
351                   
352                   input:
353                   	none
354                   output:
355                   	window handle
356                   */
357                   static HWND WineCreateWindow( HINSTANCE hInstance )
358                   {
359                   	// initialize the window class attributes.
360 cs130_ryutaro 1.2 	WNDCLASS windowClass;
361                   	//windowClass = new WNDCLASS;
362                   	windowClass.lpszClassName = "Hidden_Winsock_Window";
363                   	windowClass.style = CS_HREDRAW | CS_VREDRAW;
364                   	windowClass.lpfnWndProc = WndProcedure;
365                   	windowClass.cbClsExtra = 0;
366                   	windowClass.cbWndExtra = 0;
367                   	windowClass.hInstance = hInstance;
368                   	windowClass.hIcon = NULL;
369                   	windowClass.hCursor = NULL;
370                   	windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
371                   	windowClass.lpszMenuName = NULL;
372                   	RegisterClass(&windowClass);
373 cs130_ryutaro 1.1 
374                   	// create window
375                   	return CreateWindow( 
376                   		"Hidden_Winsock_Window", 
377                   		"Winsock Window", 
378                   		WS_OVERLAPPEDWINDOW,
379                           CW_USEDEFAULT, 
380                   		CW_USEDEFAULT,
381                           CW_USEDEFAULT,
382                           CW_USEDEFAULT,
383                           NULL,
384                           NULL,
385                           hInstance,
386                           NULL 
387                   		);
388                   }
389                   
390                   /* server */
391                   static DWORD WINAPI WineRunServer()
392                   {
393                   	// Retrieve an instance
394 cs130_ryutaro 1.1 	HINSTANCE hInstance = GetModuleHandle( NULL );
395                   
396                   	// Create a window
397                   	HWND hwnd = WineCreateWindow( hInstance );
398                   	if( hwnd == NULL ){
399 cs130_ryutaro 1.3 		trace( "Window could not be created %ld\n", GetLastError() );
400 cs130_ryutaro 1.1 		ExitThread( TH_WINDOW_ERROR );
401                   	}
402                   	
403                   	// start winsock	
404                   	WSADATA wsaData;
405                   	if( WSAStartup_w( MAKEWORD( 2, 2 ), &wsaData ) != 0 ){
406                   
407                   		// print out the Error Code to be thorough
408 cs130_ryutaro 1.3 		trace( "WSAStartup() failed with error code: %d\n", WSAGetLastError() );		
409 cs130_ryutaro 1.1 		ExitThread( TH_START_ERROR );
410                   	}
411                   
412                       // Create a socket.
413                       SOCKET sock = socket_w( AF_INET, SOCK_STREAM, IPPROTO_TCP );
	if( sock == INVALID_SOCKET ){
414 cs130_ryutaro 1.3 		trace( "socket error: %d\n", WSAGetLastError() ); 
415 cs130_ryutaro 1.1 		ExitThread( TH_SOCKET_ERROR );
416                       }
417                   
418                       // Bind the socket.
419 cs130_ryutaro 1.2     SOCKADDR_IN sockAddr;
420 cs130_ryutaro 1.1     sockAddr.sin_family = AF_INET;
421                       sockAddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );
422                       sockAddr.sin_port = htons( PORT_NUM );
423                       if( bind( sock, (SOCKADDR*) &sockAddr, sizeof( sockAddr ) ) == SOCKET_ERROR ){

424 cs130_ryutaro 1.3 		trace( "bind failed weith error code %d\n", WSAGetLastError() );
425 cs130_ryutaro 1.1         closesocket( sock );
426                   		ExitThread( TH_BIND_ERROR );
427                   
428                   	}
429                   
430                       // Listen on the socket.
431                   	if ( listen( sock, 1 ) == SOCKET_ERROR ){
432 cs130_ryutaro 1.3 		trace( "listen error with error code %d.\n", WSAGetLastError() );
433 cs130_ryutaro 1.1 		closesocket( sock );
		ExitThread( TH_LISTEN_ERROR );
	}
434                   
435                   	// make the socket asynchronous and notify of read, write, connect and close events
436                   	if( WSAAsyncSelect( sock, hwnd, ASYNC_EVENT, FD_WRITE | FD_ACCEPT |FD_READ | FD_CLOSE ) == SOCKET_ERROR ){
437                   
438 cs130_ryutaro 1.3 		trace( "WSAAsyncSelect Failed %d\n", WSAGetLastError() );
439 cs130_ryutaro 1.1 		closesocket( sock );
440                   		ExitThread( TH_SELECT_ERROR );
441                   
442                   	}
443                   
444 cs130_ryutaro 1.2 	trace( "listening and going to loop %ld\n", GetCurrentThreadId() );
445 cs130_ryutaro 1.1 	
446                   	BOOL retVal;
447                   	MSG msg;
448                   	while( ( retVal = GetMessage( &msg, NULL, 0, 0 ) ) != 0 ){ 
449                   
450                   		if( retVal == -1 ){
451                   
452                   			// handle the error and possibly exit
453 cs130_ryutaro 1.3 			trace( "GetMessage error %ld\n", GetLastError() );
454 cs130_ryutaro 1.1 			closesocket( sock );
455                   			ExitThread( TH_MSG_ERROR );
456                   		}
457 cs130_ryutaro 1.3 
458 cs130_ryutaro 1.1 		// Translate and dispatch the message
459                   		TranslateMessage( &msg ); 
460                   	    DispatchMessage( &msg );
461                   
462                   	}
463                   
464                   	return 0;
465                   }
466                   
467                   /* client */
468                   static DWORD WINAPI WineRunClient()
469                   {
470                   	// Retrieve an instance
471                   	HINSTANCE hInstance = GetModuleHandle( NULL );
472                   
473                   	// Create a window
474                   	HWND hwnd = WineCreateWindow( hInstance );
475                   	if( hwnd == NULL ){
476 cs130_ryutaro 1.3 		trace( "Window could not be created %ld\n", GetLastError() );
477 cs130_ryutaro 1.1 		ExitThread( TH_WINDOW_ERROR );
478                   	}
479                   
480                   	// start winsock	
481                   	WSADATA wsaData;
482                   	if( WSAStartup_w( MAKEWORD( 2, 2 ), &wsaData ) != 0 ){
483                   
484                   		// print out the Error Code to be thorough
485 cs130_ryutaro 1.3 		trace( "WSAStartup() failed with error code: %d\n", WSAGetLastError() );		
486 cs130_ryutaro 1.1 		ExitThread( TH_START_ERROR );
487                   	}
488                   
489                   	// Create a socket.  -- This is a TCP test
490                       SOCKET sock = socket_w( AF_INET, SOCK_STREAM, IPPROTO_TCP );
491                       if ( sock == INVALID_SOCKET ) {
492 cs130_ryutaro 1.3 		trace( "socket returned with error code: %d\n", WSAGetLastError() );
493 cs130_ryutaro 1.1 		ExitThread( TH_SOCKET_ERROR );
494                   	}
495                   
496                   	// make the socket asynchronous and notify of read, write, connect and close events
497                   	// this is the client socket
498                   	if( WSAAsyncSelect( sock, hwnd, ASYNC_EVENT, FD_WRITE | FD_CONNECT | FD_READ | FD_CLOSE ) == SOCKET_ERROR ){
499 cs130_ryutaro 1.3 		trace( "WSAAsyncSelect Failed %d\n", WSAGetLastError() );
500 cs130_ryutaro 1.1 		closesocket( sock );
501                   		ExitThread( TH_SELECT_ERROR );
502                   	}
503                   
504                   	/* connect */
505 cs130_ryutaro 1.2     SOCKADDR_IN sockAddr;
506 cs130_ryutaro 1.1     sockAddr.sin_family = AF_INET;
507                       sockAddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );
508                       sockAddr.sin_port = htons( PORT_NUM );
509                    	if( connect( sock, (SOCKADDR*) &sockAddr, sizeof( sockAddr ) ) == SOCKET_ERROR ){
510                   		if( WSAGetLastError() != WSAEWOULDBLOCK ){
511 cs130_ryutaro 1.3 			trace( "Failed to connect.: %d\n", WSAGetLastError() );
512 cs130_ryutaro 1.1 			closesocket( sock );
513                   			ExitThread( TH_CONNECT_ERROR );
514                   		}
515                       }
516                   
517                   	BOOL retVal;
518                   	MSG msg;
519                   	while( ( retVal = GetMessage( &msg, NULL, 0, 0 ) ) != 0 ){ 
520                   
521                   		if( retVal == -1 ){
522                   
523                   			// handle the error and possibly exit
524 cs130_ryutaro 1.3 			trace( "GetMessage error %ld\n", GetLastError() );
525 cs130_ryutaro 1.1 			closesocket( sock );
526                   			ExitThread( TH_MSG_ERROR );
527                   		}
528                   
529                   		// Translate and dispatch the message
530                   		TranslateMessage( &msg ); 
531                   	    DispatchMessage( &msg );
532 cs130_ryutaro 1.3 
533 cs130_ryutaro 1.1 	}
534                   	return 0;
535                   }
536                   
537                   /* close thread handles and finish up winsock dll */
538                   static void WineThreadCleanUp()
539                   {
540                   	if( ServerThread.handle )
541                   		CloseHandle( ServerThread.handle );
542                   
543                   	if( ClientThread.handle )
544                   		CloseHandle( ClientThread.handle );	
545                   }
546                   
547                   /* creates the buffer that the client sends */
548                   static void WineCreateFile()
549                   {
550                   	/* initialize just in case */
551                   	memset( FileBuf, 0, sizeof( FileBuf ) );
552                   
553                   	/* just customize this any way you want */
554 cs130_ryutaro 1.1 	memset( FileBuf, 'W', PACKET_SZ );
555                   	memset( FileBuf + PACKET_SZ, 'I', PACKET_SZ );
556                   	memset( FileBuf + ( 2 * PACKET_SZ ), 'N', PACKET_SZ );
557                   	memset( FileBuf + ( 3 * PACKET_SZ ), 'E', 3 );
558                   	FileBuf[FILE_SZ - 1] = (char) EOF;
559                   }
560                   
561 cs130_ryutaro 1.2 START_TEST( WineWinsockAsyncTest )
562 cs130_ryutaro 1.1 {
563                   	// Create the file that we are going to send.
564                   	WineCreateFile();
565                   
566                   	// Initialize server and client threads
567                   	memset( &ServerThread, 0, sizeof( ServerThread ) );
568                   	memset( &ClientThread, 0, sizeof( ClientThread ) );
569                   
570                   	// create server thread	
571                   	ServerThread.handle = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)WineRunServer, 
572                   		NULL, 0, &ServerThread.id );
573                   
574                   	if( ServerThread.handle == NULL ){
575                   
576 cs130_ryutaro 1.3 		trace( "CreateThread failed %ld\n", GetLastError() );
577 cs130_ryutaro 1.1 		WineThreadCleanUp();
578                   		return;
579                   	}
580                   
581 cs130_ryutaro 1.2 	trace( "%ld: server thread %ld created\n", GetCurrentThreadId(), ServerThread.id );
582 cs130_ryutaro 1.1 
583                   	// Wait for three seconds to let server start
584                   	DWORD waitRet = WaitForSingleObject( ServerThread.handle, SERVER_START_TIME );
585                   	if( waitRet == WAIT_FAILED ){
586                   		
587                   		// WaitForSingleObject failed for whatever reason
588 cs130_ryutaro 1.3 		trace( "WaitForSingleObject failed with error code %ld\n", GetLastError() );	
589 cs130_ryutaro 1.1 		WineThreadCleanUp();
590                   		return;
591                   
592                   	}
593                   
594                   	// get the exit code of the server - error if not STILL_ACTIVE
595                   	DWORD threadStatus = 0;
596                   	if( GetExitCodeThread( ServerThread.handle, &threadStatus ) == 0 ){
597                   		
598 cs130_ryutaro 1.3 		trace( "GetExitCodeThread failed with error code %ld\n",GetLastError() );
599 cs130_ryutaro 1.1 		WineThreadCleanUp();
600                   		return;
601                   
602                   	}
603                   
604 cs130_ryutaro 1.2 	trace( "%ld: server started successfully now creating client thread\n",  GetCurrentThreadId() );
605 cs130_ryutaro 1.1 
606                   	// Create client thread in suspended state
607                   	ClientThread.handle = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)WineRunClient, 
608                   		NULL, 0, &ClientThread.id );
609                   
610                   	if( ClientThread.handle == NULL ){
611                   
612 cs130_ryutaro 1.3 		trace( "CreateThread failed %ld\n", GetLastError() );
613 cs130_ryutaro 1.1 		WineThreadCleanUp();
614                   		return;
615                   	}	
616                   	
617 cs130_ryutaro 1.2 	trace( "%ld: client thread %ld created. Now wait.\n", GetCurrentThreadId(), ClientThread.id );
618 cs130_ryutaro 1.1 
619                   	// Wait for this server to suspsend itself
620                   	HANDLE threadHandles[NUM_THREADS_TO_WAIT] = { ServerThread.handle, ClientThread.handle };
621                   	waitRet = WaitForMultipleObjects( NUM_THREADS_TO_WAIT, threadHandles, TRUE, MAX_WAIT_TIME );
622                   	if( waitRet == WAIT_FAILED ){
623                   		
624                   		// WaitForSingleObject failed for whatever reason
625 cs130_ryutaro 1.3 		trace( "WaitForMultipleObjects failed with error code %ld\n", GetLastError() );	
626 cs130_ryutaro 1.1 		WineThreadCleanUp();
627                   		return;
628                   
629                   	}
630                   	else if( waitRet == WAIT_TIMEOUT ){
631                   
632 cs130_ryutaro 1.3 		trace( "Timed out while waiting for threads to finish\n" );
633 cs130_ryutaro 1.1 		WineThreadCleanUp();
634                   		return;
635                   
636                   	}
637                   
638                   	// clean up the threads
639                   	WineThreadCleanUp();
640                   
641 cs130_ryutaro 1.2 	trace( "%ld: main thread exiting...\n", GetCurrentThreadId() );
642                   }

Rizwan Kassim
Powered by
ViewCVS 0.9.2