Reputation: 393
I am trying to create a client/server application which communicates through Sockets. But when I receive data it randomly messed up and does not always (sometimes) show the correct data. The code I use to receive data:
private static void ReceiveCallback(IAsyncResult AR)
{
try
{
Socket socket = (Socket)AR.AsyncState;
if (SocketConnected(socket))
{
int received = socket.EndReceive(AR);
byte[] dataBuf = new byte[received];
Array.Copy(_buffer, dataBuf, received);
string text = Encoding.ASCII.GetString(dataBuf);
if (!text.Contains("GET") && !text.Contains("HTTP") && text != null)
{
Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + ":" + text);
}
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
}
}
catch
{
}
}
can someone explain me why this happends? Thanks in advance!
Also, I have tried to check untill it finds a character (which is on the end of every response '-' but that did not work). Unfortunatley this was the result:
Upvotes: 0
Views: 1137
Reputation: 345
Your socket code looks fine to me. Characters encoding format in the .Net world is "Unicode", you should convert the bytes you receive to Unicode instead of ASCII :
string text = Encoding.Unicode.GetString(dataBuf);
Upvotes: 0
Reputation: 3043
You have to loop on the socket receive until you get your entire message.
This also means that you must have an application level protocol. What defines a message?
A termination character? Then loop on the read until you get that character.
A count of characters? Then loop on the read until you get that many characters.
Is the length of the message at the front of the message? Then loop until you get enough bytes to get the length, then loop until you get the entire message.
Upvotes: 1
Reputation: 63772
I assume your socket is a TCP socket, since you're dealing with something like HTTP.
TCP deals with streams, not messages. So when you do your read, at most _buffer.Length
bytes are read from the stream. This means that you can easily read just a part of the response - or rather, the response will be split between multiple callbacks. When you read enough by chance, everything works as expected. This is especially true when testing on localhost, because Windows treats localhost TCP very differently from the non-localhost case. But when it so happens that you don't read enough, text
will not contain the whole response - and your data is broken.
Additionally, when received
is zero, it means the other side has closed the stream and you should stop doing BeginReceive
.
Upvotes: 1