1

I have a Struct to send over a socket to a client. Both the Client and the Server is on the same architecture so there is no endian problem. I receive the int values properly. But not able to receive the char[] values properly. This is the structure.

struct Packet {
int id;
int number;
char data[256];
};

In the Server side I serialize the data and write to the client.

struct Packet *s = new Packet();
s->id= htonl(1000);
s->number= htonl(7788);
memcpy(s->data, "MESSAGE", 7);

n =  write(NewSockFD , s ,sizeof(s) );

In the Client side I deserialize the data.

n = read(SockFD , Buffer , sizeof(Buffer));
struct Packet *s = (struct Packet*)Buffer;
char b[256];
int i = ntohl(s->id);
int j = ntohl(s->number);
memcpy(b, s->data, sizeof(s));

I receive the id and number values correctly. Problem is with the data value. What I'm doing wrong here??..

Aruna Karunarathna
  • 981
  • 2
  • 23
  • 55

1 Answers1

1

In your code, you use sizeof(s). This will be the size of a Packet*, not a Packet. Replace it with sizeof(*s) to get the correct size.

Additionally, since the values of data are not all initialised, you cause undefined behaviour by reading from it. You need to initialise all the elements one way or the other (the shortest way would be to do char data[256] { }; in the struct definition).

Also since this is C++, you don't need to say struct Packet, you can say just Packet, unless you also have a function named Packet. But it appears in your code only half the time which means you don't, so you can just drop it.

And as Chris G mentioned, you have another problem after you fix that, which is that you're copying an entire Packet into a char[] only big enough to hold a Packet's data. Change

memcpy(b, s->data, sizeof(s))

to

memcpy(b, s->data, sizeof(s->data))

And realise that this data may not be nul-terminated if the sender didn't do it for you (which you may want to take precautions against).

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • 1
    In addition to that, you're copying `sizeof(Packet)` into `s->data` which is only of `sizeof(Packet.data)` length. – Chris G Jan 18 '13 at 05:21
  • Hmm Thanks a lot for correcting my errors. I corrected them but still the result is the same. I'm not reading any value in the data. :( – Aruna Karunarathna Jan 18 '13 at 05:32
  • Client Code struct Packet *s = (Packet*)Buffer; char b[256]; int i = ntohl(s->id); int j = ntohl(s->number); memcpy(b, s->data, sizeof(s->data)); – Aruna Karunarathna Jan 18 '13 at 05:42
  • @SethCarnegie Server code is the same as above. I tried to initialize char data[256] { }; in struct give me error. I changed the sizeof(s) to sizeof(*s). – Aruna Karunarathna Jan 18 '13 at 05:50
  • @Zeus what is the declaration of `Buffer`? – Seth Carnegie Jan 18 '13 at 05:53
  • @SethCarnegie char Buffer[1024]; I didnt initialize any values for that. – Aruna Karunarathna Jan 18 '13 at 05:56
  • @Zeus your code is trying to read 1024 bytes before it prints the values. It should only read `sizeof(Packet)` bytes. Have you tried printing the return values of the `read` calls? They can indicate errors. – Seth Carnegie Jan 18 '13 at 06:00
  • @SethCarnegie It's really strange that when I change the id , number from the server side. Each time I'm getting the id = 1000 and number = 7788 and the number of bytes read was 8 in the client side. What might be the reason??.. – Aruna Karunarathna Jan 18 '13 at 06:14
  • @Zeus I don't know, other than you didn't change `sizeof(s)` to `sizeof(*s)`. – Seth Carnegie Jan 18 '13 at 06:17