【问题标题】:Recvfrom and WiresharkRecvfrom 和 Wireshark
【发布时间】:2019-09-16 10:07:18
【问题描述】:

我与服务器通信,我使用套接字(sock_raw ..)发送消息,它工作正常,客户端(我)发送消息,服务器接收正确的消息,但是当服务器需要发送对我(客户)来说,客户没有从 recv 中检索正确的信息。

我在两次调用 server->client 时检索到这个:

buffer = [E] | len_buffer = [2]
buffer = [E] | len_buffer = [2]

但是我的缓冲区需要等于这个数据并且有这个大小:

第一次调用(10 字节十六进制数据)

第二次调用(2 字节的十六进制数据)

这就是我使用 recvfrom 函数的方式(t->sock 是服务器的套接字 fd,t->msg_recv 是为从服务器接收 msg 而创建的缓冲区,t->_recv 是 sockaddr* 结构接收):

if (recvfrom(t->sock, t->msg_recv, sizeof(t->msg_recv), 0, \
    (struct sockaddr *)&t->_recv, \
    (socklen_t[1]){sizeof(struct sockaddr_in)}) < 0) {
        perror("recvto()");
        exit(84);
    }

Barmar 这里是 Wireshark 消息发送的输出:

这里是 send 和 recvfrom 在同一个函数上的代码:

int len = 0;
    if (sendto(t->sock, t->buffer, t->ip->tot_len, 0,
               (struct sockaddr *)&t->_sin, sizeof(t->_sin)) < 0) {
      perror("sendto()");
      exit(84);
    }
    if ((len = recvfrom(t->sock, t->msg_recv, sizeof(t->msg_recv), 0, \
    (struct sockaddr *)&t->_recv, \
    (socklen_t[1]){sizeof(struct sockaddr_in)})) < 0) {
        perror("recvto()");
        exit(84);
    }

【问题讨论】:

  • 为什么行尾有反斜杠? C 不需要,除非在宏中。
  • 你怎么知道客户没有收到正确的信息?
  • 你在哪里设置len_buffer
  • “我只收到一个大小为 2 的 E”是什么意思? recvfrom() 返回数据包的长度,但你不要在任何地方分配它。
  • 您是否尝试将缓冲区打印为字符串?它不是字符串,而是二进制数据。 E 是十六进制第一行末尾的45 字节,后面是一个零字节。由于您使用的是原始套接字,因此您会在缓冲区中获得 IP 和 UDP 标头。

标签: c sockets wireshark recvfrom


【解决方案1】:

缓冲区不是字符串,它是二进制数据,所以你不应该用%s打印它。

调用recvfrom时需要获取缓冲区的长度。然后使用循环以%02X 格式打印每个字节。

len = recvfrom(t->sock, t->msg_recv, sizeof(t->msg_recv), 0, \
    (struct sockaddr *)&t->_recv, \
    (socklen_t[1]){sizeof(struct sockaddr_in)});
if (len < 0) {
        perror("recvto()");
        exit(84);
}
for (int i = 0; i < len; i ++) {
    printf("%02X ", t->msg_recv[i]);
    if (i % 16 == 15) {
        printf("\n");
    } else if (i % 16 == 7) {
        printf(" ");
    }
}
printf("\n");

【讨论】:

  • %X 需要一个无符号整数,因此您可能必须在那里使用强制转换。
  • 正常吗?我的 len,所以 recvfrom 的返回总是等于 0。为什么? @Barmar
  • @ZahreddineLaidi 返回值 0 表示“文件结束”;在套接字的情况下,这意味着另一侧的写入端已断开连接。或者,这可能意味着您的代码错误;检查你的括号。
  • @ZahreddineLaidi 确保在 if 语句中的赋值周围正确添加了括号。这是一个常见的错误。如果没有正确执行,则将len 设置为&lt; 的结果。
  • 我已将作业拆分为单独的语句以使其更清晰。
猜你喜欢
  • 2021-12-18
  • 1970-01-01
  • 1970-01-01
  • 2016-01-29
  • 1970-01-01
  • 1970-01-01
  • 2010-12-08
  • 1970-01-01
  • 2011-08-07
相关资源
最近更新 更多