【发布时间】:2011-02-10 14:56:35
【问题描述】:
我有一个 C 程序,它通过套接字以 UDP 数据包的形式从大型机接收数据。 C 程序的主机正在从 Unix(大端)更改为 Linux(小端),程序不再工作。我目前没有更改大型机客户端程序的选项。
程序执行recvfrom 并将数据接收到一个字符数组中。以前,我们能够简单地将这个缓冲区转换为与从 MF 传递的内容相匹配的结构,并且一切正常。现在,由于不同的字节对齐方式,到结构的映射失败。这是结构和一些代码。
struct CCClntPkt
{
unsigned short packet_type;
unsigned short reply_socket;
unsigned long msg_ID;
unsigned short msg_length;
unsigned char client_string[250];
};
之前用于将接收到的数据缓冲区转换为该结构的代码如下所示:
char BCpacket_in[MAX_PACKET];
struct CCClntPkt *pClntPkt;
<snip>
rcv_cnt = recvfrom(BCServerSocket, BCpacket_in,
sizeof(BCpacket_in),0x0,(struct sockaddr *)&from,
&fromlen);
if (rcv_cnt > 0)
{
pClntPkt = (struct CCClntPkt *) &BCpacket_in;
}
我能够通过使用ntohs 获得 packet_type 和 reply_socket 的正确值,但是字符字段 client_string 被破坏了。我还尝试在结构之前放置pragma pack(1),在结构之后放置pragma pack(0),但似乎仍然存在对齐问题。
我还尝试了从BCpacket_in 移位值,并且能够获得 packet_type 和 reply_socket 的正确值,但无法弄清楚如何提取 ulong msg_ID。代码是:
packet_type = BCpacket_in[0] << 8;
packet_type |= BCpacket_in[1];
reply_to_socket = BCpacket_in[2] << 8;
reply_to_socket |= BCpacket_in[3];
/*
msg_ID = BCpacket_in[4] << 24;
msg_ID |= BCpacket_in[5] << 16;
msg_ID |= BCpacket_in[6] << 8;
msg_ID |= BCpacket_in[7];
*/
在这一点上我很困惑,所以任何帮助表示赞赏。我不是这个程序的原作者,我的 C 知识非常有限。不过,我不介意做这项工作,所以我也希望能提供任何相关的参考资料。谢谢!
【问题讨论】:
-
假设它是 32 位机器,您注释掉的代码应该可以解决问题。 char
标签: c sockets endianness