Reputation: 3077
I had a code (lets suppose a simple chat application), I used Tcp with sync. but since Async way is better at all although it is harder to setup, I decided to change the way from sync to async. but now I am facing some problems using async.
Let me explain my problem by the following code:
public void Send(byte[] message, Socket connection)
{
connection.BeginSend(message,
0,
message.Length,
SocketFlags.None,
new AsyncCallback(OnSend),
connection);
}
and on OnSend method, I just use connection.EndSend(result) where result is IAsyncResult. but when I then call Send method twice like the following code, OnReceive call back will receive both of them as a one single message.
Send(Encoding.Unicode.GetBytes("Hello"));
Send(Encoding.Unicode.GetBytes("Bye"));
my OnReceiveMethod will use Console.WriteLine(message); where message is the string received from peer. and the output using sync way must be
Hello
Bye
but in async way I receive it as a one message not two, so it is printed
HelloBye
Sincerely yours, Peyman Mortazavi
Upvotes: 0
Views: 912
Reputation: 41
I must say I don't really agree with simply switching to synchronous sockets to overcome this problem. A much better approach would be using a Queue<string>
(for example) where you put messages in when call send.
Then you have your asynchronous socket dequeue packets from this queue, and send the next one when the current one is done sending, until the queue is empty.
Then you could choose not to call BeginSend again until there are messages in the queue again.
Upvotes: 4
Reputation: 43743
With the synchronous call, you are guaranteeing that the first message is completely sent before you send the second one. With the asynchronous methods, however, you are just adding the two messages to the outgoing queue, waiting to be sent. If you happen to hit it at the right time, it may send them as two separate messages, but since you add them both so fast, it's more than likely going to send both together. If you think of TCP/IP socket communication as a single ongoing stream of data, you'll be much better off. You need to format your messages in a way where you can determine where they begin and end. When you receive data through the socket, you should keep adding the received messages to a buffer until you've determined (based of the formatting of the data) that you have received a complete message. You should not be relying on each read from the socket to be a single complete message. You should expect that it may only be a partial message or even multiple messages.
Upvotes: 2