【问题标题】:Typecasting a character buffer to a struct coming from a socket将字符缓冲区类型转换为来自套接字的结构
【发布时间】:2014-07-14 06:00:42
【问题描述】:

我正在使用以下代码从套接字读取数据:

while (true) 
{

        int len = 0;
        ioctl(sd, FIONREAD, &len);
        if (len > 0)
        {
                len = read(sd, databuf, len);                   
        }

        else
                std::cout << "error" << std::endl;
}

有来自套接字的结构流。 结构的大小由我定义。

那么我该如何阅读这样的结构:

 typedef struct
 {
      short msglen;
      short id;
      int seqno;
 }HEADER;

我想对它进行类型转换,但我不知道该怎么做。字符缓冲区将一个接一个地包含 多个 结构。我只需要读取前 8 个字节即可获得第一个。

此外,还有一个 while 循环,因为我从网络接收到连续的多播消息流。

【问题讨论】:

  • std::memcpy(&amp;header, buffer, sizeof(header));
  • @Jayesh 我在接收方。另外,我与服务器没有联系。他们已经给出了ip和端口。以及结构定义和大小。就是这样。
  • 如果你真的是通过网络发送数据,你需要考虑字节序、内置数据大小和填充。简单地复制数据似乎很不安全。查看对象序列化。
  • @juanchopanza 你是对的。但在这种情况下,协议已经指定他们将以小端序发送数据,而我在 intel x86 机器上。他们还指定了与我的机器匹配的 POD 的大小。另外,遗憾的是我不能进行对象序列化,因为这个应用程序非常以性能为中心。

标签: c++ c linux sockets networking


【解决方案1】:

符合标准且安全的方法是使用memcpy

HEADER header;
char buffer[/*size*/]; 

/* read data into buffer */

std::memcpy(&header, buffer, sizeof(header));

现代编译器完全有能力优化掉函数调用。

不要尝试将buffer 转换为reinterpret_cast 之类的东西。这是未定义的行为,因为它违反了严格的别名规则(您可以通过charunsigned char 类型的glvalue 访问任何类型对象的存储值,但反过来不成立)。

附带说明,typedef struct { /* ... */ } HEADER; 是 C 主义。只需struct HEADER { /* ... */ };

【讨论】:

    【解决方案2】:
    std::memcpy(&header, buffer, sizeof(header));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-27
      • 1970-01-01
      • 1970-01-01
      • 2016-03-09
      • 2021-03-13
      • 2018-04-19
      相关资源
      最近更新 更多