0

我正在构建一个客户端和一个通过 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 的结构体,输出将是:
Sending ACK with value: 2

在 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
ERROR] Invalid ACK (1)。

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

4

5 回答 5

3

这很可能不是问题,但我相信下面您的 client.c 代码段中的第二行应该是 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 是您之前发送的数据包的响应?

于 2009-11-19T11:45:28.990 回答
1

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

最好多注意并一次一个字节地序列化字段。

于 2009-11-19T10:59:11.210 回答
1

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

于 2009-11-19T11:02:31.603 回答
0

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

于 2009-11-19T11:04:20.930 回答
0

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

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

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

于 2009-11-19T12:05:46.157 回答