1

我与服务器通信,我使用套接字(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 的输出:

在此处输入图像描述

这是同一函数上的 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);
    }
4

1 回答 1

0

缓冲区不是字符串,它是二进制数据,所以你不应该用%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");
于 2019-04-26T22:26:28.217 回答