in this qusetion C# Receiving Packet in System.Sockets a guy asked: "In my Client Server Application i wondered how to make a packet and send it to the server via the Client Then on the server i recognize which packet is this and send the proper replay"
and showed the example of his way of implementing the 'packet recognizer'. He got an answer that his way of 'structuring the message' is bad, but no explanation and code example followed by the answer.
So please, can anybody show the example of a good code, which should do something like this, but proper way:
[client]
Send(Encoding.ASCII.GetBytes("1001:UN=user123&PW=123456")) //1001 is the ID
[server]
private void OnReceivePacket(byte[] arg1, Wrapper Client)
{
try
{
int ID;
string V = Encoding.ASCII.GetString(arg1).Split(':')[0];
int.TryParse(V, out ID);
switch (ID)
{
case 1001://Login Packet
AppendToRichEditControl("LOGIN PACKET RECEIVED");
break;
case 1002:
//OTHER IDs
break;
default:
break;
}
}
catch { }
}
TCP ensures that data arrives in the same order it was sent - but it doesn't have a concept of messages. For instance, say you send the following two fragments of data:
1001:UN=user123&PW=123456
999:UN=user456&PW=1234
On the receiving end, you will read 1001:UN=user123&PW=123456999:UN=user456&PW=1234
and this might take one, two or more reads. This may even arrive in two packets as:
1001:UN=user123&PW=12
3456999:UN=user456&PW=1234
This makes it very had to parse the message correctly. The other post mentions sending the length of a packet before the actual data, and that indeed solves the problem, as you can determine exactly when one message ends and the next starts.
As an example, client and server could agree that each message starts with 4 bytes containing the length of the message. The receiver could then simply:
C# conveniently has the BitConverter
class that allows you to convert the integer to a byte[] and vice versa.