Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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?

That is correct. I don't know if you can check if its already been called though (apart from your own custom flag). Its quite possible that two calls to BeginRecieve wouldn't do anything anyways; check the documentation. BradleyDotNET Nov 7, 2014 at 17:09 Socket , or rather the OS, checks for this itself. If you attempt to call BeginReceive while another receive is already in progress, it will throw an exception representing the socket error WSAEALREADY (I think). After all, there isn't much sense in trying to receive into two buffers from the same socket simultaneously! But if you ask whether there is a property on Socket that tells you whether an operation is in progress, the answer is no (it'd be useless anyway because of the inescapable race condition). You can implement your own locking if you need to. Anton Tykhyy Nov 7, 2014 at 17:13 You should not call begin receive in a way that would cause a reentrancy.. that's for sure. if you encounter a situation where you need a flag to know if you called it or not - it probably means your architecture is incorrect. G.Y Nov 7, 2014 at 17:15 @AntonTykhyy: "If you attempt to call BeginReceive while another receive is already in progress, it will throw an exception" This is not correct. In fact, issuing multiple receive operation (i.e. calling BeginReceive() multiple times) is a strategy commonly used when dealing with IOCP-based I/O (as the Socket class is). The trick is, while the buffers will be filled in the order in which they were submitted via the receive operations, the completion events may occur out of order. So the caller does need to keep track of their buffer order and ensure they are processed correctly. Peter Duniho Nov 7, 2014 at 17:41 Feel free to have a look at my .NET Sockets repo on Github which uses BeingReceive/EndReceive patterns. And here is the C# version. perry Nov 7, 2014 at 17:51

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).

Just to be sure I understand your answer: I think you're saying there should be exactly TWO calls to BeginReceive() - one where the socket is first connected and one in the callback/handler. The first BeginReceive() is only called once, all subsequent calls to BeginReceive are from the handler, right after EndReceive(). Is this correct? user316117 Nov 7, 2014 at 17:50 For simplest implementation, yes. As I mentioned in the comments to the question, you can call BeginReceive() multiple times, but then you have to do housekeeping to make sure you process the received data in the right order. I'll add some clarification to the answer. Peter Duniho Nov 7, 2014 at 18:01

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.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question . Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers .