[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference jamin::pathworks32

Title:Digital PATHWORKS 32
Moderator:SPELNK::curless
Created:Fri Nov 01 1996
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:337
Total number of notes:1612

261.0. "PW 32 API gives problems with WSA send function" by GIDDAY::COOK (Matt Cook , CSC Sydney Australia) Wed Apr 30 1997 02:53

	
	G'day All,

		I have a customer with a problem with the PW32 API
	please excuse me but I have no programming experiance so
	if something is not clear please let me know.

	The customer said he is using the WSA send call with a completion
	if he runs this in step by step debug mode he gets a sucess for
	the WSA send but the completion fails with C0000005 Access Violation
	if he runs without the completion it works, it also works fine
	when using MS TCP/IP , the problem occurs with DECNET, the OS
	is Windows NT v4.0.

	Thanks,
	Matt. 
T.RTitleUserPersonal
Name
DateLines
261.1JAMIN::OSMANEric Osman, dtn 226-7122Wed Apr 30 1997 11:0510
    
    What do you mean about "the completion".  The send call should return
    a value indicating how many characters were sent, or the error
    indicator of SOCKET_ERROR.  In this second case, the WSAGetLastError call
    can be made to determine the error code.
    
    Are you seeing something different ?
    
    /Eric
         
261.2WSASend using overlapped IOJAMIN::KROBINSONWed Apr 30 1997 14:20119
The problem is with overlapped IO and is new for Winsock 2.  You call WSASend( ... , lpCompletionRoutine) .  The
operation is initiated and the application gets a callback when complete. 

I have seen this problem myself.  An application that runs fine fails in the debugger.  It can be caused by a
couple of problems:
1) not using a unique WSAOVERLAPPED structure (initialized to zero) for EACH overlapped call.
2) bugs in the DECnet SPI pws2dnet.wsp.

I have fixed the bugs in pws2dnet.wsp and this fix will be available in PATHWORKS 32 v 7.0A . I have included a
programming example below.  If the customer's problem is urgent, mail me and I will try to troubleshoot it.

Ken Robinson
PATHOWRKS 32 
WinSock 2 DECnet
[email protected]



// Overlapped IO
// There are two methods of using overlapped IO with Winsock2 described below:
	
// 1) Callback functions
	
	// you must declare an overlapped completion routine that will be called when the overlapped operation is
done
	void __declspec(dllexport) CALLBACK CompRoutine(DWORD dwError, 	DWORD cbTransferred, 
							LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags) 
	{
		printf("completion  dwError: %d, cbTransferred: %d, dwFlags: %d\n",	dwError, cbTransferred,
dwFlags);
	}

	// You need a different overlapped structure for each overlapped send or receive.
	// Do not modify any field in the WSAOVERLAPPED structure.
	WSAOVERLAPPED overlap;

	// You must create an overlapped socket
	socknew = WSASocket(AF_DECnet, SOCK_STREAM, DNPROTO_NSP, 0, 0, WSA_FLAG_OVERLAPPED);

	// Then call WSASend or WSARecv
	rc = WSASend(socknew, lpwsabufsend, buffercount, lpbytessent, 0, &overlap, &CompRoutine);  
	if (rc != 0) {
		rc = WSAGetLastError();
		if (rc == WSA_IO_PENDING) { 
			// the overlapped operation is pending
			// lpbytessent is not updated

			// this thread needs to be in an alertable wait state to allow the completion routine to
be called
			// SleepEx() or WSAWaitForMultipleEvents() with fAlertable set to TRUE will work
			
			SleepEx(INFINITE, TRUE);  
			// the completion routine will be called and this thread will wake up

		} else {
			// handle error
		}
	}else {
		// send completed immediately
		// lpbytessent will be updated
		// the completion routine will not be called
	}
	

// 2) Event Objects

	// You need a different overlapped structure for each overlapped send or receive.
	WSAOVERLAPPED overlap;

	// You need a unique event object for each overlapped structure.
	// This is the only field you should modify in the WSAOVERLAPPED structure.  And you should only modify it
when you
	// create or close an event object.
	overlap.hEvent = WSACreateEvent();

	// You must create an overlapped socket
	socknew = WSASocket(AF_DECnet, SOCK_STREAM, DNPROTO_NSP, 0, 0, WSA_FLAG_OVERLAPPED);

	// Then call WSASend or WSARecv
	rc = WSARecv(socknew, lpwsabufrecv, buffercount, lpbytesrcvd, 0, &overlap,0);  
	if (rc != 0) {
		rc = WSAGetLastError();
		if (rc == WSA_IO_PENDING) { 
			// the overlapped operation is pending
			// lpbytesrcvd is not updated
		} else {
			// handle error
		}
	}else {
		// recv completed immediately
		// lpbytesrcvd will be updated
		// the completion routine will not be called
	}

	// Now you need to get the results of the overlapped receive. You can have multiple overlapped operations
pending on a 
	// socket, so the WSAOVERLAPPED structure is used to retreive the results of a particular operation.
	// There are three possible ways to do this:
	
	// 1: Call WSAGetOverlappedResult with fWait set to TRUE.  This blocks until the overlapped operation is
done
	rc = WSAGetOverlappedResult(socknew, &overlap, lpbytesrcvd2, TRUE, lpflags); 

	// 2: Call WSAWaitForMultipleEvents() and then WSAWSAGetOverlappedResult with fWait set to FALSE.
	//	  This method can be used to wait until more than one overlapped operation is done.
	rc = WSAWaitForMultipleEvents(1, &overlap.hEvent, TRUE, WSA_INFINITE, FALSE); 
	// This blocks until the overlapped operation is done
	rc = WSAGetOverlappedResult(socknew, &overlap, lpbytesrcvd2, FALSE, lpflags); 

	// 3: Poll by calling WSAGetOverlappedResult() repeatedly with fWait set to FALSE.
	do {
		rc = WSAGetOverlappedResult(socknew, &overlap, lpbytesrcvd2, FALSE, lpflags); 
	} while (rc == FALSE);

	// make sure you close the event object when you are done with it
	WSACloseEvent(overlap.hEvent);
	overlap.hEvent = WSA_INVALID_EVENT;

	// end