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

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

Rizwan Kassim
Powered by
ViewCVS 0.9.2