【问题标题】:read() and write() to sockets returning corrupted valuesread() 和 write() 到返回损坏值的套接字
【发布时间】:2012-11-29 12:01:56
【问题描述】:

我尝试使用write() 命令写入套接字。我需要写入的数据是结构类型的,它包含charint 数据类型值。但是当我将数据写入服务器套接字时,int 变量的值被破坏了。我总是收到16777216 的值。

我正在从Solaris 机器写到Linux 机器。 Solaris 是 32 位机器,Linux 是 64 位机器。这对我的问题有影响吗?

我使用htonl/ntohl 和反之亦然将integer 值从服务器传递到服务器。但是,如果我将整个结构类型写入套接字,我该如何使用它呢?谁能帮我解决这个问题?

PCHAR data = NULL;
int size = sizeof(WSMsg);
int retry = 10;
data = new char [sizeof(WSMsg)];
memcpy(data, msg, sizeof(WSMsg));
int n = write(fd, &data[0], size);

这是我的代码部分。这里WSMsg 是结构类型,具有intchar 类型值。

我正在从包含数字、char 类型值的数据库表中写入特定行。我正在写这样的不同表格的不同行。因此,如果我需要使用htonl/ntohl,那么我需要将所有这些数字转换为网络字节。由于我有 20 个或更多表及其具有整数类型值的结构,因此将所有这些转换并发送出去对我来说将是一项耗时的工作。

【问题讨论】:

  • 为什么不直接用结构调用write呢? IE。 write(fd, msg, sizeof(WSMsg))
  • 我可以这样做,但是当我在另一端收到数据时,我的整数值已损坏。如果我将数据从 Solaris 传输到 Solaris 或从 Linux 传输到 Linux,一切正常。当我从 Solaris 写入 Linux 或反之亦然时,就会出现问题。
  • 好吧,“Solaris”通常表示“SPARC”,它是大端的,而“Linux”通常表示“x86 或 ARM”。因此,编写一个导致损坏的完整结构也就不足为奇了。
  • @Damon 那么有什么办法可以解决这个问题吗??
  • 正确使用htonl/ntohl 应该可以工作,但显然您必须对结构的每个成员都这样做,就像序列化一样,并在另一侧“反序列化”结构。

标签: c++ linux sockets solaris


【解决方案1】:

您的字节顺序似乎有问题。有几种不同的方法可以解决这个问题:一种是查看serialization,即将您发送的结构转换为与字节顺序问题无关的格式;另一种解决方案是创建结构的副本,并使用例如htons/htonl 需要的地方:

WSMsg temp = *msg;
temp.someShortField = htons(temp.someShortField);
// etc.

当然在接收端做相反的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-31
    • 2015-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    相关资源
    最近更新 更多