iTEgg
iTEgg

Reputation: 8342

C# asynchronous socket BeginSend EndReceive

I am new to programming and I am confused about asynchronous socket programming.

For example let's say I have two BeginSends, one right after another. The first sends a million chars and the second sends only 64 chars.

Due to the asynchronous nature won't the second BeginSend complete before the first one?

If so how can I tell the recieved data at EndRecieve, belongs to which message?

Upvotes: 3

Views: 18364

Answers (2)

Fuzz
Fuzz

Reputation: 1805

You really shouldn't call two BeginSend's after one another. I think that you'll end up seeing exceptions thrown if this happens.

You have to call an EndSend before calling another BeginSend. This is typically done in side the callback function.

Check out the example Using an Asynchronous Client Socket at MSDN. In the callback the EndSend is called, and then a ManualResetEvent called "sendDone" is set. This is a form of inter-thread communication in which the callback is signaling to your main thread that the asynchronous send is completed. This then allows your program to cue up the next piece of data.

  • Call BeginSend from your main thread to send the first 1,000,000 bytes
  • Your main thread can check on a semaphore or something like the ManualResetEvent to trigger it to send the next 64 bytes. Your other option is to use a queue for the data to send
  • When the data has finished sending, the callback you passed in to the BeginSend will be called.
  • In this call back, you will call EndSend. Follow this then setting the ManualResetEvent, or what ever inter-thread trigger you wish to use.

The simplest option, which I recall doing once, is to call BeginSend for the next piece of data in the callback for the first piece of data being done.

e.g.

int NumBytesSent; // member variable containing how many bytes you have sent so far
string Message;   // Message to send that is large

When you call BeginSend, pass in a chunk of say 100 bytes (pick a larger number for more efficient transfers, but not too large) to send and increment NumBytesSend by 100. Next, in your callback for the previous send being completed you can check if NumBytesSent < Message.Length, and if it is then send the next chunk of the Message.

This is how you would send a file you send a bunch of bytes at once, and just keep sending chunks of the file until it is all sent.

I highly recommend making a simple client/server to do something like sending a complete file over a connection. Also review the MSDN documents and the many other examples out and about in the web.

Getting a good grip on this will help you with lots of other C# topics as working asynchronously (or using delegates/callbacks) is very common for .NET

Upvotes: 8

Mark Byers
Mark Byers

Reputation: 837926

The BeginSend method includes a parameter AsyncCallback callback. If you use two different callbacks, you can see which one completed first.

But if you are trying to send both messages on the same connection, you will have problems. You should wait until the first message is completely sent before sending the second.

Upvotes: 1

Related Questions