c - 套接字 : Byte order mixed up

标签 c unix networking ipv6 endianness

我正在编写一个程序,它使用 libpcap 嗅探 IPv6 数据包并通过 TCP/IP 将这些数据包发送到服务器。

由于 IP(v6) 数据包不是多字节数据,而更像是“一堆位”,因此我不使用任何编码(如 htons...)。

奇怪的是,我将数据包输出到 stdout 并且它们看起来不错,但是当我通过网络传输它们时,它们都变得困惑了。我使用 netcat 来确保我的服务器没有问题。一个数据包正确到达,而另一个数据包具有不同的字节顺序。有什么想法吗?

编辑: 好吧,那么令人敬畏的“不”是正确的,我被 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

最佳答案

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

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

现在我已经实现了一个原始的“协议(protocol)”,告诉我的接收者数据包的大小并因此分开接收它们,它们确实按顺序到达。

关于c - 套接字 : Byte order mixed up,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13585446/

相关文章:

C编译时cmath错误

linux - shellscript从文件中读取变量

java - 无法安装新软件/检查更新 eclipse

c - 帮助使用 LD_PRELOAD

c++ - C - 将指针转换为指向 void 的指针

c - 按位运算 : Need to create a large integer, 但只能声明一个8bit整数

java - java中c++的pwd.h lib的等价物

linux - 如何在路径包含空格的文件上使用 `diff`

algorithm - 在伪代码中使用动态二维数组或 HashMap ?

LAN 中的 PHP 和服务器到服务器通信