WSARecv Problems.

Started by
9 comments, last by laeuchli 22 years, 3 months ago
Hey all, I've written a IOCP server for my game, and it works great in debug mode. However, when I recompile in release mode, the recv code stops working :-(. The recive thread code is below. Can someone show me what I'm doing wrong, and why changing to release mode messed it up?
  
UINT HandleIncoming(LPVOID pParam)
{

	WSAOVERLAPPED overlap[MAXCLIENTS];
	for(int q=0;q<MAXCLIENTS;q++)
	{
	::memset( &overlap[q], 0, sizeof( overlap[q]) );
	}
	do{
		if(recive==true)
		{
		for(int i=0;i<currentopensocket;i++)
		{
			DWORD bytesread;
			buffer.buf=info[i].postionofship;
			buffer.len=sizeof(info[i].postionofship);
			WSARecv(ServerSocket[i].Socket,&buffer,1,&bytesread,&flags,&overlap[i],NULL);
			ServerSocketState[i]=recving;

		}
		recive=false;
		}
	}while(1==1);
	return 1;
}



 

  
Thanks, Jesse www.laeuchli.com/jesse/ [edit: replaced cpp tags with source tags] Edited by - Magmai Kai Holmlor on January 13, 2002 8:52:37 PM
Advertisement
Maybe try posting your code in a [source ][/source ] tag so that it is readable... (remove the space at the end of ''source '' in the tag example above).


-Brannon
-Brannon
That works in a debug build?!

For starters, I''m pretty sure you need to check the return code from WSARecv - it could complete immedietly - if it doesn''t it''ll return an erro and WSAGetError will return WASEWOULDBLOCK. In this case you need to hang on the event in the overlapped structure - which you never create (another problem).

Did you create the socket with the WSA_FLAG_OVERLAPPED flag? Or do you _want a blocking operation? If that''s the case, you don''t pass an overlapped structure into WSARecv - you pass NULL. Again you need to check the error code, because it will return with an error when the socket is closed or when WSACleanup is called, in which case you don''t want to process the data in the buffer.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
No, he''s passing a valid overlapped structure. The final param to WSARecv is the completion routine (which you don''t want if you''re using IOCPs).

One thing you should probably do is derive your own WSAOVERLAPPED structure.. something like:

  typedef struct{	WSAOVERLAPPED Overlapped;	DWORD BytesRead;	BYTE* Buffer;	DWORD BufferSize;        DWORD Flags;} MYOVERLAPPED;  


And cast that to a (WSAOVERLAPPED*) when calling WSARecv() (or pass &my_overlapped.Overalapped, which ever looks cleaner to you... they both do the same).

For things like BytesRead, you need to keep the storage for that valid until the recv actually completes, be it immediately, or in the IOCP thread. Try keeping a pool of overlapped structures that you get one from when calling WSARecv, and return one to when the recv completes. Also, even if the recv completes immediately, the notification will still be posted to the IOCP, so just handle it there (unless you want to deal with ignore dup notifications... I had to learn this one the hard way...).

Other than that, you should definitely be checking the result of WSARecv(). That might give you an indication of what is failing. Maybe you are getting ERROR_INVALID_PARAM (or the WSA equivalent) in release, but you wouldn''t know.



-Brannon
-Brannon
quote:
For things like BytesRead, you need to keep the storage for that valid until the recv actually completes, be it immediately, or in the IOCP thread.


If you are referring to the lpNumberOfBytesRecvd parameter passed to WSARecv, you are incorrect. When using Overlapped I/O and WSARecv doesn''t complete immediately (i.e. GetLastError() returns WSA_IO_PENDING), lpNumberOfBytesRecvd does not get used. lpNumberOfBytesRecvd only gets updated if WSARecv completes immediately.

You determine the number of bytes transferred by using the cbTransferred parameter of GetQueuedCompletionStatus.



Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
Yeah, you''re right, I knew that, but didn''t think about it enough last night. I believe the Flags parameter is still used though.


-Brannon
-Brannon
I believe the flag parameter is ignored as well...though I''m not positive. I''ve never retained the flag variable when calling WSARecv in my IOCP servers and I haven''t encountered any errors as of yet.

It would be interesting to look into it.

Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
If it''s not retained, then I don''t think you''d have any way of getting the MSG_PARTIAL (or whatever) value... not that UDP or TCP support partial messages .. but some other protocols do.


-Brannon
-Brannon
Er, he never creates an event to use for overlapped IO, nor creates a completion port, nor creates a completion port and an event, nor gives it a completion routine... so I don''t see how it would ever work... _unless it''s a blocking socket.

Overlapped IO functions doesn''t always return WSAEWOULDBLOCK, they will will return S_OK/NOERROR if data is already queued when you issue a request (I had a nasty bug in my CComPort class for ignoring this case). In which case you need that cBytesRecv, otherwise I think it''s garbage.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
He states that he created an IOCP server, so I am assuming that somewhere he sets up the IOCP.

laeuchli- you are setting up the socket and IOCP correctly right? If you still can''t get this to work, maybe you should post your IOCP thread function, and snippets from how you create your sockets and the IOCP.


-Brannon
-Brannon

This topic is closed to new replies.

Advertisement