serialize and deserialize structures in sockets

2020-07-27 16:12发布

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??..

1条回答
Ridiculous、
2楼-- · 2020-07-27 16:28

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).

查看更多
登录 后发表回答