【问题标题】:Client/Server: Integer always received as 1 (C-programming)客户端/服务器:整数总是作为 1 接收(C 编程)
【发布时间】:2010-12-18 06:19:59
【问题描述】:

我正在构建一个客户端和一个通过 TCP 交换数据的服务器程序,当操作成功时,我无法将 ACK 确认从服务器发送回客户端。我已经设法从客户端向服务器发送了一个包含各种成员的结构,然后服务器应该通过向客户端发送一个确认结构 ID 的整数来响应。

在 server.c 我有这个功能:

int sendACK(int socket, int ack_int){

    int com_result;
    int ACK = htonl(ack_int);

    printf("\n\tSending ACK with value: %i", ack_int);

    com_result = send(socket, &ACK, sizeof(ACK), 0);

    if (com_result == -1) {
        perror("\n\t[ERROR] Send ACK");
        return 0;
    }

    return 1;

}

这个函数被 server.c 中的另一个函数调用,如下所示:

int ACK = myStruct->ID;
sendACK(socket, ACK);

所以,如果我刚刚收到一个 ID 为 2 的结构,输出将是:
发送值为 2 的 ACK

在 client.c 中,我收到这样的 ACK:

int ACK = 0;
data_size  = sizeof(myStruct.ID);
com_result = read(client_socket, &ACK, data_size);
ACK = ntohl(ACK);

if (com_result == -1) {
    perror("\n\t[ERROR] Read");
} else {
    printf("\n\tRecieved %i of %i bytes", com_result, data_size);
    if (ACK != myStruct.ID) {
        printf("\n\t[ERROR] Invalid ACK (%i).", ACK);
    }
}

但是收到的 ACK 总是值为 1,所以客户端的输出是:
Recieved 4 of 4 bytes
错误] ACK (1) 无效。

为什么没有收到值为 2 的整数,我该如何解决这个问题?

【问题讨论】:

  • 首先你需要缩小你的范围。要排除客户端使用 telnet 连接到您的服务器,排除服务器使用 netcat 作为您的客户端连接到的服务器。

标签: c macos tcp int send


【解决方案1】:

我会检查您的主要发送方/接收方代码处理的数据量是否正确。

如果您的发送者发送了 20 个字节,然后是一个 4 个字节的 ACK,但接收者在尝试读取 ACK 之前只读取了 16 个字节,那么您可能会遇到这种问题。

如果您要发送可变长度数据(即带有字节数前缀),则通常会混淆传输的字节数是否实际上包括发送字节数所需的额外字节...

【讨论】:

    【解决方案2】:

    这很可能不是问题,但我认为下面的 client.c sn-p 中的第二行应该是 sizeof(ACK)。

    int ACK = 0;
    data_size  = sizeof(ACK); // was: sizeof(myStruct.ID);
    com_result = read(client_socket, &ACK, data_size);
    ACK = ntohl(ACK);
    

    另外,根据您的数据流,您是否可能实际读取正确,而 ACK 是您之前发送的数据包的响应?

    【讨论】:

    • 我怀疑这是问题的原因。即使不是,它仍然是完全错误的。
    • 刚刚运行了代码,在程序中发现了一个对 sendACK 的恶意调用,它正在向客户端传输一个 1 值。谢谢:)
    【解决方案3】:

    我无法弄清楚您在上面粘贴的代码有什么问题。我建议退出 Wireshark 或其他套接字跟踪程序,然后查看线路上的位。

    【讨论】:

      【解决方案4】:

      为了调试它,你可以使用 wireshark。执行 wireshark 并设置其选项以侦听所需的端口。您将看到通过网络在数据包内实际发送的内容。这将让您了解问题出在服务器、客户端还是两者兼而有之。

      【讨论】:

        【解决方案5】:

        你不应该像这样发送整个值,你需要更加注意序列化。例如,如果发送机器上的 sizeof (int) 与接收机器上的不同,这可能会失败,在这种情况下,您将读取错误的字节数。

        最好小心一点,一次一个字节地序列化字段。

        【讨论】:

          猜你喜欢
          • 2019-10-27
          • 2017-12-29
          • 2020-06-19
          • 2016-02-14
          • 2022-06-16
          • 2016-02-09
          • 2022-01-09
          • 2018-08-10
          • 1970-01-01
          相关资源
          最近更新 更多