套接字:字节顺序混乱

4
我正在编写一个程序,使用libpcap嗅探IPv6数据包,并通过TCP/IP将这些数据包发送到服务器。由于IP(v6)数据包不是多字节数据,而更像“一堆位”,因此我没有使用任何编组(如htons…)。奇怪的是,我将数据包输出到标准输出,它们看起来很好,但当我通过网络传输它们时,它们变得混乱了。我使用netcat确保我的服务器没有问题。其中一个数据包正确到达,而另一个数据包的字节顺序不同。有什么想法吗?
编辑:好吧,真棒的“nos”是对的,我被hexdump愚弄了。“hexdump -c”显示了正确的输出。然而,我的程序的服务器部分(说实话,并没有得到与发送/客户端同样的关注,我会在发布代码之前重写它)有时会进行2次读取并获得正确的数据,大多数情况下会一次性获取所有数据并打乱顺序。
(发送)代码如下:
struct pb_elem {
    size_t size;
    u_char *data;
};
-------------------------    

int send_all(int sockfd, packet_buf pbuf) {
int res = 0, n, i;
uint offset = 0, byteleft = 0;
struct pb_elem *packet;

res = packet_buf_dequeue(pbuf, &packet);
while (res == 0) {
    byteleft = packet->size;
    offset = 0;

    /* DEBUG */ fprintf(stderr, "DEBUG: send new packet\n");
    printf("DEBUG: Data size: %zu\n", packet->size);
    for (i=0; i < packet->size; i++) {
        printf(((i % 2 == 1) ? "%02X " : "%02X"), (unsigned int)*(packet->data+i));
    }
    printf("\n");

    do {
        n = send(sockfd, packet->data+offset, byteleft, 0);
        if (n == -1)
            break;
        offset = n;
        byteleft -= n;
        /* DEBUG */ fprintf(stderr, "DEBUG: send: offset: %u, byteleft: %u\n", offset, byteleft);
    } while (byteleft > 0);

    if (n == -1)
        fprintf(stderr, "Error: could not send whole packet.");

    free(packet->data);
    free(packet);

    res = packet_buf_dequeue(pbuf, &packet);
}

return 0;
}

嗅探程序(发送方)的示例输出(2个ICMPv6数据包)如下:

IPv6Buffer started
DATA:
0800 277B 1EBD 0A00 2700 0001 86DD 6000 0000 0035 3A40 2001 0DB8 BBBB 0000 0000 0000 0000 0001 2001 0DB8 BBBB 0000 0000 0000 0000 0102 8000 160B 116F 0001 09BD B450 0000 0000 DD2A 0500 0000 0000 CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CA
DATA:
0800 277B 1EBD 0A00 2700 0001 86DD 6000 0000 0035 3A40 2001 0DB8 BBBB 0000 0000 0000 0000 0001 2001 0DB8 BBBB 0000 0000 0000 0000 0102 8000 3E08 116F 0002 0ABD B450 0000 0000 B42C 0500 0000 0000 CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CA
DEBUG: start_sending
DEBUG: Data size: 107
0800 277B 1EBD 0A00 2700 0001 86DD 6000 0000 0035 3A40 2001 0DB8 BBBB 0000 0000 0000 0000 0001 2001 0DB8 BBBB 0000 0000 0000 0000 0102 8000 160B 116F 0001 09BD B450 0000 0000 DD2A 0500 0000 0000 CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CA
DEBUG: Data size: 107
0800 277B 1EBD 0A00 2700 0001 86DD 6000 0000 0035 3A40 2001 0DB8 BBBB 0000 0000 0000 0000 0001 2001 0DB8 BBBB 0000 0000 0000 0000 0102 8000 3E08 116F 0002 0ABD B450 0000 0000 B42C 0500 0000 0000 CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CA

我接收到的服务器/接收器程序内容:

IPv6Buffer started
DEBUG: start_receiving()
DEBUG: pre-accept in receive_data()
Data size: 214
0800 277B 1EBD 0A00 2700 0001 86DD 6000 0000 0035 3A40 2001 0DB8 BBBB 0000 0000 
0000 0000 0001 2001 0DB8 BBBB 0000 0000 0000 0000 0102 8000 2598 1280 0001 B3C8 
B450 0000 0000 2381 0400 0000 0000 CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE CAFE 
CAFE CAFE CAFE CAFE CAFE CA08 0027 7B1E BD0A 0027 0000 0186 DD60 0000 0000 353A 
4020 010D B8BB BB00 0000 0000 0000 0000 0120 010D B8BB BB00 0000 0000 0000 0001 
0280 007A 9712 8000 02B4 C8B4 5000 0000 00CD 8004 0000 0000 00CA FECA FECA FECA 
FECA FECA FECA FECA FECA FECA FECA FECA FECA FECA FECA

1
这些是完整的ICMPv6回显请求数据包,包括伪头部。虽然其中一些是多字节数据,但通常您会像32位整数一样编组/解组,如果您想要例如1337号在每个平台上实际上是1337。我想你可以说数据包是以网络字节顺序排列的,我希望始终保持这种方式。我还没有对数据进行计算,而且数据包只有在这种形式下才真正有效。 - Benjamin Maurer
@netcoder 糟糕,我知道我忘了什么 ^^ 感谢你提醒我。 - Benjamin Maurer
这与Unix套接字无关。 - Steve-o
1个回答

0

虽然我不完全确定为什么要更改字节顺序,但我有一个解决方法。

我刚刚实现了接收端的一个简单版本,尝试接收尽可能多的数据以适应MTU大小的缓冲区。通常情况下,两个数据包都会被读取并组合在一起。

现在,我已经实现了一个原始的“协议”,告诉我的接收器数据包的大小,因此它们会按顺序到达。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接