(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                   
 50                   /* struct def */
 51                   typedef struct 
 52                   {
 53                   	DWORD id;
 54                   	HANDLE handle;
 55 cs130_ryutaro 1.1 	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                   
 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 cs130_ryutaro 1.1 		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                   static int WSAStartup_w( WORD wVersionRequired, LPWSADATA lpWSAData )
 93                   {
 94                   	int errCode = 0;
 95                   	
 96                   	// WSAVERNOTSUPPORTED test
 97 cs130_ryutaro 1.1 	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.2 		trace( "%d: WSAVERNOTSUPPORTED test failed with error code: %d\n", __LINE__, 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.2 		trace( "%d: WSAFAULT test failed with error code: %d\n", __LINE__, 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.2 		trace( "%d: WSAStartup() failed with error code: %d\n", __LINE__, 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.2 		trace( "%d: WSAEAFNOSUPPORT test failed: %d %d\n", __LINE__, 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.2 		trace( "%d: WSAEPROTONOSUPPORT test failed: %d %d\n", __LINE__, 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.2 		trace( "%d: WSAEPROTONOSUPPORT test failed: %d %d\n", __LINE__, 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.2 		trace( "%d: Error at socket(): %d\n", __LINE__, 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.2 						trace( "%d: accept error %d\n", __LINE__, 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.2 						trace( "%c", buf[i] );
248 cs130_ryutaro 1.1 						i++;
249                   					}
250 cs130_ryutaro 1.2 					trace( "\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.2 							trace( "%c", buf[j] );
274 cs130_ryutaro 1.1 							j++;
275                   						}
276 cs130_ryutaro 1.2 						trace( "\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                   							ResumeThread( ServerThread.handle );
288                   							ExitThread( 0 );
289                   						}
290                   					}
291                                       break;
292                   
293                   				case FD_WRITE:
294                   
295                   					// don't do anything here for server
296                   					if( GetCurrentThreadId() == ServerThread.id )
297                   						break;
298                   
299                   					// enter an infinite loop
300                   					BOOL notDone = TRUE;
301                   				    while( notDone ){
302                   
303                   						// determine how many bytes to send
304                   						int bytesToSend = 0;
305                   						if( sizeof( FileBuf ) - ClientThread.bytesSent < PACKET_SZ ){
306 cs130_ryutaro 1.1 
307                   							// the bytes remaining to send is smaller than packet size
308                   							bytesToSend = (int) ( sizeof( FileBuf ) - ClientThread.bytesSent );
309                   							notDone = FALSE;
310                   
311                   						}
312                   						else{
313                   
314                   							// the bytes remaining is greater than or equal to PACKET_SZ
315                   							bytesToSend = PACKET_SZ;
316                   
317                   						}
318                   							
319                   						memcpy( buf, FileBuf + ClientThread.bytesSent, bytesToSend ); 
320                   						ClientThread.bytesSent += bytesToSend;
321                   						
322                   						// send the packet off to the Server if it is filled
323                   						if( send( socket, buf, bytesToSend, 0 ) == SOCKET_ERROR ){
324                   
325                   							// check if the network buffer is full and can send no more
326                   					        // data. If so then break from the loop
327 cs130_ryutaro 1.1 					        if( WSAGetLastError() == WSAEWOULDBLOCK ){
328 cs130_ryutaro 1.2 						          // break from the loop – buffer is full
329 cs130_ryutaro 1.1 						          break;
330                   						    }
331                   							else{ // another error
332                   								return 0;
333                   							}
334                   						}
335                   						
336 cs130_ryutaro 1.2 						trace( "%ld sent: ", GetCurrentThreadId() );
337 cs130_ryutaro 1.1 						j = 0;
338                   						while( j < PACKET_SZ &&  buf[j] != (char)EOF ){
339 cs130_ryutaro 1.2 							trace( "%c", buf[j] );
340 cs130_ryutaro 1.1 							j++;
341                   						}
342 cs130_ryutaro 1.2 						trace( "\n" );
343 cs130_ryutaro 1.1 					}
344                   					break;
345                               }
346                        }
347                        return DefWindowProc( hWnd, msg, wParam, lParam );
348                   }
349                   
350                   /* 
351                   Creates a hidden window object.
352                   
353                   input:
354                   	none
355                   output:
356                   	window handle
357                   */
358                   static HWND WineCreateWindow( HINSTANCE hInstance )
359                   {
360                   	// initialize the window class attributes.
361 cs130_ryutaro 1.2 	WNDCLASS windowClass;
362                   	//windowClass = new WNDCLASS;
363                   	windowClass.lpszClassName = "Hidden_Winsock_Window";
364                   	windowClass.style = CS_HREDRAW | CS_VREDRAW;
365                   	windowClass.lpfnWndProc = WndProcedure;
366                   	windowClass.cbClsExtra = 0;
367                   	windowClass.cbWndExtra = 0;
368                   	windowClass.hInstance = hInstance;
369                   	windowClass.hIcon = NULL;
370                   	windowClass.hCursor = NULL;
371                   	windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
372                   	windowClass.lpszMenuName = NULL;
373                   	RegisterClass(&windowClass);
374 cs130_ryutaro 1.1 
375                   	// create window
376                   	return CreateWindow( 
377                   		"Hidden_Winsock_Window", 
378                   		"Winsock Window", 
379                   		WS_OVERLAPPEDWINDOW,
380                           CW_USEDEFAULT, 
381                   		CW_USEDEFAULT,
382                           CW_USEDEFAULT,
383                           CW_USEDEFAULT,
384                           NULL,
385                           NULL,
386                           hInstance,
387                           NULL 
388                   		);
389                   }
390                   
391                   /* server */
392                   static DWORD WINAPI WineRunServer()
393                   {
394                   	// Retrieve an instance
395 cs130_ryutaro 1.1 	HINSTANCE hInstance = GetModuleHandle( NULL );
396                   
397                   	// Create a window
398                   	HWND hwnd = WineCreateWindow( hInstance );
399                   	if( hwnd == NULL ){
400 cs130_ryutaro 1.2 		trace( "%d: Window could not be created %ld\n", __LINE__, GetLastError() );
401 cs130_ryutaro 1.1 		ExitThread( TH_WINDOW_ERROR );
402                   	}
403                   	
404                   	// start winsock	
405                   	WSADATA wsaData;
406                   	if( WSAStartup_w( MAKEWORD( 2, 2 ), &wsaData ) != 0 ){
407                   
408                   		// print out the Error Code to be thorough
409 cs130_ryutaro 1.2 		trace( "%d: WSAStartup() failed with error code: %d\n", __LINE__, WSAGetLastError() );		
410 cs130_ryutaro 1.1 		ExitThread( TH_START_ERROR );
411                   	}
412                   
413                       // Create a socket.
414                       SOCKET sock = socket_w( AF_INET, SOCK_STREAM, IPPROTO_TCP );
	if( sock == INVALID_SOCKET ){
415 cs130_ryutaro 1.2 		trace( "%d: socket error: %d\n", __LINE__, WSAGetLastError() ); 
416 cs130_ryutaro 1.1 		ExitThread( TH_SOCKET_ERROR );
417                       }
418                   
419                       // Bind the socket.
420 cs130_ryutaro 1.2     SOCKADDR_IN sockAddr;
421 cs130_ryutaro 1.1     sockAddr.sin_family = AF_INET;
422                       sockAddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );
423                       sockAddr.sin_port = htons( PORT_NUM );
424                       if( bind( sock, (SOCKADDR*) &sockAddr, sizeof( sockAddr ) ) == SOCKET_ERROR ){

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

Rizwan Kassim
Powered by
ViewCVS 0.9.2