1

I'm writing code for an application using sockets where I have to send integers and strings over the network, but I'm having trouble packing the data into a buffer for transmission. I tried doing this:

sendline[0] = htons(3);
sendline[1] = htons(strlen(argv[3]));
for(int i = 0; i < strlen(argv[3]); i++)
{
    sendline[i + 2] = argv[3][i];
}
sendline[2 + strlen(argv[3])] = htons(atoi(argv[4]));
sendline[3 + strlen(argv[3])] = '\0';

but it doesn't work. Where am I going wrong here? Also, what would be the best way to serialize this kind of data?

This is my deserialization code :

case '3': // switching on the value of buf[0]
{
    int i;
    int len = ntohs(buf[1]);
    char* ch = (char*)malloc(len * sizeof(char));
    for(i = 0; i < len; i++)
    {
        ch[i] = buf[i + 2];
    }
}
npn
  • 381
  • 1
  • 5
  • 14

2 Answers2

0

You should user htonl()and ntohl(), if you are serializing 32 bit (4 byte) integers.

send:

int my_integer = INT32_MAX;
uint32_t data = htonl(my_integer);
write(s, &data, sizeof(data));

recv:

uint32_t data;
read(s, &data, sizeof(data));
int my_integer = ntohl(data);

There are many questions on SO already describing serialization and the htonl()/ntohl() functions, but beware of those omitting endianess. Remember to check return values of read() and write().

As for the "strings", do not serialize them, if they are char data describing ASCII text. UTF8 also works without serialization, but beware of UTF-16. The important thing to grasp about endianess early on is that it refers to byte order and not the order of bits within a byte. IIRC C guarantees that the presentation form of a single byte, so it appears the same on all C platforms.

thuovila
  • 1,960
  • 13
  • 21
-1

Buffer sent/received via sockets consists of char, which is 1 byte long. Integer/uint16_t type is longer.

So what you really do, when you try to assign?

sendline[0] = htons(3);

sendline[0] is 1 byte long, but htons(3) is 2 bytes long, so you truncate it. Similarly you use sendline[1] by:

sendline[1] = htons(strlen(argv[3]));

Obviously your buffer gets corrupted.

Send integer numbers in one socket and strings in other, convert integers to strings or do not overwrite your buffer (so you have to use sizeof(int) on some places)

Community
  • 1
  • 1
Peter Petrik
  • 9,701
  • 5
  • 41
  • 65
  • Yes that was a typo, sorry. Edited – npn Mar 21 '14 at 08:12
  • You cannot possibly 'overwrite `sendline[1]` by assigning anything to `sendline[0].` What he does need is (a) a cast and (b) some code to handle all the bytes of the integer returned by `htons().` At the moment he is simply *truncating* the value. -1 – user207421 Mar 21 '14 at 09:05
  • @EJP I have tried to explain why the current approach is not working properly, but obviously I hit a limit of my C knowledge:). Feel free to edit my answer and remove any misleading facts. Thanks – Peter Petrik Mar 21 '14 at 09:14
  • If I convert my integers to strings during serialization, how will I deserialize them unless I know the length of each string? – npn Mar 21 '14 at 21:25