[TCP]Can't read packet

Started by
0 comments, last by rip-off 15 years, 4 months ago
why this don't work :( Client: #define CHAT_MSG 0x01 typedef struct chat_msg { unsigned char packetid; char *msg; } ChatMsg; // WSAStartup(), socket(), connect() ---> initialized! ChatMsg chat; ChatMsg.packetid = CHAT_MSG; ChatMsg.msg = "Hi all!"; if(send(client_sock, (const char *) &chat, sizeof(chat), 0) == SOCKET_ERROR) { MessageBox(NULL, "Error sending!, "Error!", MB_ICONEXCLAMATION); return 0; } Server: #define CHAT_MSG 0x01 typedef struct chat_msg { unsigned char packetid; char *msg; } ChatMsg; // WSAStartup(), socket(), bind(), listen(), accept() ---> initialized! ChatMsg chat; if(recv(server_sock, (char *) &chat, sizeof(chat), 0)) { printf("ERROR: Failed to receive a packet!"); return 0; } switch(chat.packetid) { case CHAT_MSG: { printf("The Message is: %s!\n", chat.msg); // <--- don't read the sended message.... } } but don't read the message! why? :(
Advertisement
You are only sending the binary representation of the chat message. This representation includes whatever bit pattern points at the string literal "Hi all!". When you read the data from the stream, the value of this bit pattern is irrelevant. The problem is that you cannot send pointers, the value of a pointer is only useful on a single machine, during a single execution.

The solution is to properly serialise the string. There are two ways, one would be to prefix the string contents with a fixed size length field, in a known endian format. The other would be to use the NUL character to denote the end of the string. Either way, at the end of the day you will have encoded the contents of the string into a sequence of bytes. This is what you send over the network.

Finally, be very aware that TCP is a stream oriented protocol, not a packet oriented one. This means that when you send a certain chunk, you can get it at the other end in different ways.

For example:
send("hello, world.");send("how are you?");


You could recv like this:
Quote:
recv: hell
recv: o, world.\0 ho
recv: w are
recv: you?\0

This is why you need to be able to distinguish where one message ends and the next begins. Here, I have chosen the rather simple rule of using NUL characters. For more complex situations, there usually isn't such a convenient marker so you will probably end up prefixing the length.

This topic is closed to new replies.

Advertisement