C++int via socket send():Linux/MacOS上TCP包中的different值

C++ int via socket send(): differnent value in TCP package on Linux / MacOS

本文关键字:TCP MacOS 包中 different Linux socket via send C++int      更新时间:2023-10-16

我有一个用C++编写的Client/Server应用程序。客户端发送一个包含三个int 32的结构(proxy_header)。这会触发服务器发回信息。问题是,如果客户端运行在OS X(El Capitan)上,服务器不会回复。Tcpdump显示发送的结构的不同值。

C++代码如下:

初始化发送到服务器的消息:

struct { int m:32; int x:32; int y:32; } proxy_header;
proxy_header.m = 0x02212102;
proxy_header.x = 1;
proxy_header.y = 1;

发送:

    {   int r;
if ((r = send(t->fd, (void*)&proxy_header, sizeof(proxy_header), 0)) != sizeof(proxy_header)) {
    error("Failed to send proxy header (%d != %d)", r, sizeof(proxy_header));
    goto error;
    }

正在等待答案-recv():

if ((r = recv(t->fd, (void*)&(proxy_answer), sizeof(proxy_answer), MSG_WAITALL)) != sizeof(proxy_answer)) {
  printf("Failed to receive ...")
    }
else {
  printf("Successfully received...");
}

该程序可在Linux上编译并运行良好。在MacOS上,我得到"接收失败…"。

tcpdump包,我发现了以下内容:

Ubuntu上,我可以看到SYN/ACK,然后从客户端到服务器的PSH响应ACK,然后从服务器到客户端的PSH回应ACK。

第一次推送(来自客户端)包含以下内容:

char peer0_0[] = { /* Packet 4 */
0x02, 0x21, 0x21, 0x02, 0x01, 0x00, 0x00, 0x00, 
0x01, 0x00, 0x00, 0x00 };

MacOS上,同样的情况发生在客户端的第一个PSH之前,该PSH被服务器确认。然后服务器只发送一个FIN。

这就是推送包含的内容:

char peer0_0[] = {
0x02, 0x21, 0x21, 0x02, 0x00, 0x00, 0x00, 0x01, 
0x00, 0x00, 0x00, 0x01 };

显然不同。。。为什么?

这看起来像是endianness(反向数据字节)的问题

考虑到从MAC操作系统客户端发送数据时会得到什么,数据格式可能是"big-endian",而服务器可能使用"little-endian"格式。(运行MAC操作系统的计算机是PowerPC吗?)
https://en.wikipedia.org/wiki/Endianness

解决此问题的一种方法是在双方(客户端和服务器)使用独立于平台端序的数据缓冲区。例如,您可以使用boost endian_buffers:
http://www.boost.org/doc/libs/1_58_0/libs/endian/doc/buffers.html

您的数据结构可能如下所示:

struct {
    little_int32_buf_t m;
    little_int32_buf_t x;
    little_int32_buf_t y;
} proxy_header;