通过套接字一致地丢失数据(但在使用本地主机连接时不会)

Losing data consistently over sockets (but not when using localhost connections)

本文关键字:主机 连接 套接字 数据      更新时间:2023-10-16

我正在尝试熟悉套接字编程。我写了一个客户端/服务器游戏,看到一些奇怪的结果。

下面是客户端部分的代码:


while(1){
        char response[100];
        memset(&buf[0], 0, sizeof(buf));
        //buf[numbytes] = '';
        socklen_t addr_len = sizeof their_addr;
        if ((numbytes = recvfrom(sockfd, buf, MAXDATASIZE-1, 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) {
            perror("recv");
            exit(1);
        }
        if (strcmp(buf, "exit 99") == 0){
            close(sockfd);
            return 0;
        }
        printf("%sn",buf);
        std::cin >> response;
        struct msgstruct message;
        message.send_data = response;
        message.length = strlen(message.send_data);
        int n   = sendto(sockfd, response, strlen(response), 0, p->ai_addr, p->ai_addrlen);
    }

这通过"服务器"进行通信,通过以下代码片段:

int StartMasterMind(int client, sockaddr_storage addr_in) 
{
    struct sockaddr_storage their_addr = addr_in;
    socklen_t addr_len;
    char buf[MAXDATASIZE];
    buf[MAXDATASIZE] = '';
    sendMsg(client, "Welcome to ... M-A-S-T-E-R-M-I-N-D.nThe game has begun.n");
// [..] redacted for clarity 
    for (int i = 0; i < 8; ++i) {
    sendMsg(client, "Please enter your guess: ");
    addr_len = sizeof their_addr;
    recv(client, buf, MAXDATASIZE-1, 0/*, (struct sockaddr *)&their_addr, &addr_len*/);
    current_try = GetInputAsColorMap(buf);
// [..] redacted for clarity -- several for() loops below here
}

//basic message structure
struct msgstruct {
        int length;
        char* send_data;
};
//basic method for sending messages
int sendMsg(int client, char* theMsg)
{
    msgstruct message;
    message.send_data = theMsg;
    message.length = strlen(message.send_data);
    return (send(client, message.send_data, message.length, 0));
}

因此,如果我通过本地主机连接:./client localhost <port>,那么一切似乎都正常:

c@ub1:~/Documents/dev$ ./client localhost 9990
client: connecting to 127.0.0.1
Welcome to ... M-A-S-T-E-R-M-I-N-D.
The game has begun.
Please enter your guess: 

但是,当从另一个 VM 通过网络连接时,我始终得到:

c@ub1:~/Documents/dev$ ./client 192.168.1.111 9990
client: connecting to 192.168.1.111
Welcome to ... M-A-S-T-E-R-M-I-N-D.
The game has begun.

请注意缺少Please enter your guess: - 我有点不知所措。我无法弄清楚为什么/何时/在哪里丢弃这些数据。正因为如此,我有点害怕继续,因为我只是假设我在某个地方有一个缓冲区会溢出并破坏一切。

你犯了所有常见的错误。您假设一个发送等于一个接收。在使用接收缓冲区时,您没有使用 recv() 返回的读取计数。您假设 TCP 是一种消息传递协议。这是一个字节流协议。