1

I've been wondering when the call back that's provided with a BeginRecieve call is triggered.

  • Is it when it received as much data as the buffer can hold? And if so - what if the data is smaller than the buffer)
  • Is it when it received one TCP/IP packet?
  • Is it something else?

I found a similair question which I will repeat as I can't put it much clearer:

Now all documentation says that the callback, as specified in BeginReceive, is called as soon as 'the data is received'. But this is rather vague: when exactly is that moment if you don't know how exactly that other process is providing data?

One criterium is that BeginReceive() is considered completed (and thus the callbask is called) when the buffer in the state object is filled upto the specified buffersize. But what if the 'delivering' process is feeding data in unknown quantities and in an irregular pattern? For instance, if it first delivers 100 bytes consecutively, and then there is a time interval of 1 millisecond and another 200 bytes follow: does BeginReceive complete with 100 bytes of incoming data? Or 300?

http://www.pcreview.co.uk/forums/exactly-beginreceive-socket-considered-completed-t2899270.html

Gabriël
  • 1,323
  • 2
  • 22
  • 34
  • I would think it would depend on the [type of socket](http://msdn.microsoft.com/en-us/library/system.net.sockets.sockettype) that it is. A datagram socket is likely to invoke the callback when a datagram has been received. Stream sockets may have timeouts, internal buffers, etc. – Damien_The_Unbeliever Jun 14 '12 at 10:18
  • Did you ever find the truth about this. I am on a quest to get the answer, and the answer on this page doesn't seem definitive. http://stackoverflow.com/questions/18418613/socket-buffers-the-data-it-receives – Niels Brinch Aug 26 '13 at 07:54

2 Answers2

0

Assuming your socket is a TCP socket. Then the callback is triggered when any data is available, but it delivers in the callback at maximum as much as the buffer size is. You need anyway a framing protocol (means you need to call multiple times BeginReceive(..) and detect and assemble the frames you sent).

Simon
  • 1,496
  • 8
  • 11
0

My experience is that it is called for any data being available without delay. This means that reads can be rather small, like 1400 bytes or so because that is on the order of the MTU size.

Reads can be multiples of that because if packets arrive out of order all of them are made visible to application the moment the logically first one arrives. You get to read from all contiguous queued packets at once in this case.

I guess your read size will increase on extremely fast connections because your application might fail to dequeue bytes as fast as the network delivers individual packets.

Sidenote: The BeginReceive-callback is called at exactly the same moment Receive would have returned. You don't get to reduce latency that way. (Latency will actually increase by a tiny amount because async operations can have higher overhead than blocking ones).

usr
  • 168,620
  • 35
  • 240
  • 369
  • For my scenario it seems very much that the callback is **not** invoked immediately - please have a look: http://stackoverflow.com/questions/18418613/socket-buffers-the-data-it-receives – Niels Brinch Aug 26 '13 at 07:52
  • @NielsBrinch I don't see evidence that this is because of async. A synchronous code path might have the same issue. – usr Aug 26 '13 at 09:22
  • I agree that it's not **because** of async. But the asker is wondering "When is callback triggered" and it doesn't seem like it's true that "... it is called for any data being available without delay" – Niels Brinch Aug 26 '13 at 12:40
  • @NielsBrinch I'd wait to see what the problem in your question was before I'd conclude that. There might be an application error or some other unrelated cause. Feel free to post an update here once we know what your issue is. – usr Aug 26 '13 at 12:43
  • Sure, you're right of course. However, in my question I already confirmed with wireshark that the packages DO arrive at the server hosting the server application gradually. – Niels Brinch Aug 26 '13 at 12:56
  • So I investigated it further and when using a synchronous socket it receives data immediately. So everything points in the direction that the BeginReceive callback doesn't happen immediately for some strange reason. – Niels Brinch Aug 27 '13 at 19:07
  • Who knows what's going on. My understanding is that async IO does not differ in behavior compared to sync IO on a very fundamental level. Maybe your threadpool is overloaded or something else if delaying callback delivery. Reproduce the issue with minimal code (yours is not minimal) on a fresh machine or VM. The issue will disappear. If it doesn't post a repro and I'll have a look. – usr Aug 27 '13 at 19:28
  • Do you really believe that async callbacks only trigger every 20s? Totally implausible. The cause is yet unknown but the infrastructure is probably not it. – usr Aug 27 '13 at 19:32
  • My code is the 'official' example from Microsoft. http://msdn.microsoft.com/en-us/library/fx6588te.aspx. I have removed all of my application logic and I am just logging the received text. I am not saying that callback happens after 20 seconds normally, I can see it working immediately on my local workstation. I am saying that under some unknown circumstances, it **is** delayed. – Niels Brinch Aug 27 '13 at 19:46
  • It's running on a server that has no load of any other kind. It only has this application running on it, except for a local SQL Express server. – Niels Brinch Aug 27 '13 at 19:47