【问题标题】:serialize and deserialize structures in sockets序列化和反序列化套接字中的结构
【发布时间】:2013-01-01 19:07:34
【问题描述】:

我有一个 Struct 可以通过套接字发送给客户端。客户端和服务器都在同一个架构上,所以不存在字节序问题。我正确接收 int 值。但无法正确接收 char[] 值。 这是结构。

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

在服务器端,我将数据序列化并写入客户端。

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

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

在客户端我反序列化数据。

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

我正确收到了 id 和 number 值。问题在于数据值。我在这里做错了什么??..

【问题讨论】:

    标签: c++ sockets serialization client-server deserialization


    【解决方案1】:

    在您的代码中,您使用sizeof(s)。这将是Packet* 的大小,而不是Packet。将其替换为 sizeof(*s) 以获得正确的大小。

    此外,由于data 的值并未全部初始化,因此通过读取它会导致未定义的行为。您需要以一种或另一种方式初始化所有元素(最短的方法是在结构定义中执行char data[256] { };)。

    另外,由于这是 C++,你不需要说 struct Packet,你可以只说 Packet,除非你还有一个名为 Packet 的函数。但它只出现在你的代码中,这意味着你没有,所以你可以放弃它。

    正如 Chris G 所提到的,在修复该问题后还有另一个问题,即您将整个 Packet 复制到 char[] 中,其大小仅足以容纳 Packetdata。改变

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

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

    并意识到如果发件人没有为您执行此data 可能不会被 nul 终止(您可能需要采取预防措施)。

    【讨论】:

    • 除此之外,您还将sizeof(Packet) 复制到s->data,这只是sizeof(Packet.data) 的长度。
    • 嗯,非常感谢您纠正我的错误。我更正了它们,但结果仍然相同。我没有读取数据中的任何值。 :(
    • 客户端代码结构包s = (Packet)Buffer;字符 b[256]; int i = ntohl(s->id); int j = ntohl(s->number); memcpy(b, s->data, sizeof(s->data));
    • @SethCarnegie 服务器代码与上面相同。我试图初始化 char data[256] { };在结构中给我错误。我将 sizeof(s) 更改为 sizeof(*s)。
    • @Zeus Buffer的声明是什么?
    猜你喜欢
    • 1970-01-01
    • 2010-09-21
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    • 2018-07-11
    • 2016-03-02
    相关资源
    最近更新 更多