【问题标题】:Unexpected behavior parsing recvfrom() message from UDP socket解析来自 UDP 套接字的 recvfrom() 消息的意外行为
【发布时间】:2020-06-08 03:23:18
【问题描述】:

目前正在使用 UDP 套接字,我试图理解以下情况。

接收缓冲区定义如下:

char buf[1024];
...
memset(&buf, 0, sizeof(buf));

& 是通过调用 recvfrom() 来完成的

size = recvfrom(sockdf, buf, sizeof(buf), MSG_WAITALL, (struct sockaddr *) &rx, (socklen_t *)&len);

我从远程获取这些数据,使用 Wireshark 确认:

01 fe 00 04 00 00 00 21 53 53 53 5f 54 54 54 54 5f 30 31 32 33 34 35 36 37 10 fe 00 10 02 ac ca fe 00 00 00 00 00 00 00 00

使用简单的for 循环来识别缓冲区内容,我得到:

for (i = 0; i < size; i++)
{
    printf("buf[%d] = 0x%x", i, buf[i]);
}

buf[0] = 0x1
buf[1] = 0xfffffffe
buf[2] = 0x0
buf[3] = 0x4
buf[4] = 0x0
buf[5] = 0x0
buf[6] = 0x0
buf[7] = 0x21
buf[8] = 0x53
buf[9] = 0x53
buf[10] = 0x53
buf[11] = 0x5f
buf[12] = 0x54
buf[13] = 0x54
buf[14] = 0x54
buf[15] = 0x54
buf[16] = 0x5f
buf[17] = 0x30
buf[18] = 0x31
buf[19] = 0x32
buf[20] = 0x33
buf[21] = 0x34
buf[22] = 0x35
buf[23] = 0x36
buf[24] = 0x37
buf[25] = 0x10
buf[26] = 0xfffffffe
buf[27] = 0x0
buf[28] = 0x10
buf[29] = 0x2
buf[30] = 0xffffffac
buf[31] = 0xffffffca
buf[32] = 0xfffffffe
buf[33] = 0x0
buf[34] = 0x0
buf[35] = 0x0
buf[36] = 0x0
buf[37] = 0x0
buf[38] = 0x0
buf[39] = 0x0
buf[40] = 0x0

我当然误解了试图获取/解析收到的消息的内容,但我无法解释原因 打印 buf[1]、buf[26]、buf[30]、buf[31] 和 buf[32] 会返回额外的 FF 吗?

使用 gdb 的相同行为

(gdb) p/x buf[26]
$3 = 0xfe
(gdb) call printf("0x%x\n", buf[26])        
0xfffffffe
$4 = 11

任何提示将不胜感激。

【问题讨论】:

  • 关于; memset(&amp;buf, 0, sizeof(buf)); 这应该会导致编译器输出警告消息。建议:memset(buf, 0, sizeof(buf)); 不通知&amp;。裸数组引用降级为数组第一个字节的地址。所以不需要(也不应该)询问数组的地址。
  • 关于; 01 fe ... fe 是一个否定字符。使用通常的符号扩展名,这将打印为 0xfffffffe

标签: c gdb printf buffer recvfrom


【解决方案1】:

它被称为符号扩展,当小于int 的有符号值是promoted 时发生(例如,用作printf 的参数时)。

避免这种情况的一种简单方法是对数组使用unsigned char(或uint8_t)而不是char

uint8_t buf[1024];

或者使用printf 格式的hh 前缀:

printf("buf[%d] = 0x%hhx", i, buf[i]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    相关资源
    最近更新 更多