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?
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With