Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct use of BeginReceive / EndReceive?

Tags:

c#

sockets

To asynchronously receive data from a socket .Net supports symmetrical BeginReceive/EndReceive calls. Basically you call BeginReceive() to start listening and to identify a callback which should be called when the data arrives. Inside the callback you call EndReceive() to extract the data and end the asynchronous read operation.

I'm writing C#/.Net software to control some industrial equipment. A control panel allows users to set up and initialize the equipment and once it's initialized BeginReceive() is called start listening for data. In the callback EndReceive() is used to extract the data, but I want to resume listening right away so I think I should call BeginReceive() again right after doing the EndReceive(). Is this correct?

If so, is there a check or test I can use elsewhere in the code to know whether BeginReceive() has already been called so I don't try to call BeginReceive() twice in a row on the same socket, before EndReceive() has been called?

like image 996
user316117 Avatar asked Nov 07 '14 17:11

user316117


2 Answers

The way you avoid calling BeginReceive() again before you've called EndReceive() is to put the call to BeginReceive() into the completion callback where you call EndReceive(). The only call to BeginReceive() that should not be executed there is, of course, the one you make immediately after the Socket has connected.

EDIT:

To be clear: it is permitted to call BeginReceive() any number of times before any receive completion happens. But when you do that, you need to make sure you do the necessary housekeeping to ensure you process the data in the right order (i.e. you process the buffers in the same order in which you submitted them via BeginReceive()).

So the above answer is about not having to do all that housekeeping and thus keeping the code simpler.

If you only ever make your subsequent calls to BeginReceive() in the same place where you are calling EndReceive(), it's trivial to keep things in order. Note though that you still need to do that right: the simplest way to ensure you are always receiving the buffers in the right order is to simply not call BeginReceive() again until after you've called EndReceive() (but still in the same method).

like image 153
Peter Duniho Avatar answered Oct 27 '22 09:10

Peter Duniho


Yes, you need to call BeginReceive after you are done receiving the data in order to get more down the road when data becomes available.

It's up to you to handle the state of the Socket where you do not call BeginReceive twice. There are properties available to let you know whether data is available, but nothing that tells you whether you are already waiting to receive data.

Most implementations of Socket end up being another wrapper class that has this logic in place so that BeginReceive is ignored if called a 2nd time. The Socket class is kind of a pain at times since you cannot cancel a BeginReceive without closing.

like image 27
TyCobb Avatar answered Oct 27 '22 08:10

TyCobb