views:

765

answers:

2

I am using the BeginReceive() and EndReceive() method for async IO using Sockets in .NET. The client sends continuous packets of data and calling EndReceive() returns the number of bytes read.

The problem is that the client is sending packets of data but data length is ZERO. It found this by analyzing the traffic in WireShark. When the length of data is Zero, the EndReceive() call just blocks there.

Is there a way to identify the ZERO length data without actually blocking on EndReceive()?

Also, the ReceiveTimeout property does not seem to work on Async methods.

Sample Source Code:

// This method runs on a separate thread
private void ProcessRequest()
{
   BeginReceive(OnClientReceive);

   // Do some work here in a loop
}

// Callback method
private void OnClientReceive(IAsyncResult result)
{
   int receivedCount = socket.EndReceive(result); // this one blocks

   // Do some work here

   // Again start listening for data
   BeginReceive(OnClientReceive);
}
A: 

Sockets in .NET deals with packets as a continuous stream of data, not on packet-by-packet basis. That's why EndReceive will block until data is available, or until the connection is ended.

If you want to capture the received data in a packet-by-packet basis, I think you need to use something like WinPcap library

Aziz
That is what I am using(WinpCap with WireShark) but the problem is not with capturing packets. The EndReceive() blocks because of which my thread blocks. I want to get out of the this blocking.
A9S6
I'm not sure if I understand correctly. You are using EndReceive() in the callback of StartReceive(), right? so, EndReceive() will wait until there is some data to read. If there is some code that you want to execute whether or not you have data, then you should not put it in the callback. Would you please explain what you're trying to capture?
Aziz
Yes, I have some code that executes after I get data from EndReceive(). But when EndReceive() blocks, the data is not processed in the callback method neither it throws an exception. It just keeps waiting there.Also, I think the ReceiveTimeout does not work with EndReceive(). I want to make this EndReceive() return and not block the callback thread (even if it returns a ZERO).
A9S6
I see, if you want to execute some code even if no data is received, then you should not put this code in the same callback thread. Can you please show some code?
Aziz
I have added some sample code to the question
A9S6
ya, I see. what I meant is that you should put the code that you want to process even without data in the ProcessRequest method. I mean that's the whole point of having async sockets
Aziz
The first thread (ProcessRequest) receives data from a server in a loop and sends it to the client. The other method OnClientReceive receives data from client async and sends it to the server. So they both need to run separately.This is also because I dont want to affect the code that is sending data to the server.
A9S6
ok. If the client didn't send anything (zero data), what would you send to the server?
Aziz
I had not come across this situation because it does not return from EndReceive() when the data is ZERO. and that is the real problem.
A9S6
that's my point, if there's no data, then there's nothing to send to the server, that's why EndReceive() waits until there's data. If you want to send something even if there's no data, then you should use a different thread (not in the callback)
Aziz
A: 

Hi, Sihori I would check socket.Available 1) if socket.Available >0 process all code in your callback "OnClientReceive" 2) if socket.Available = 0: only part "// Do some work here" should be processed 3) put some locks to avoid conflicts Jamal

Jamal