使用套接字时清除 read() 缓冲区

Clearing a read() buffer while using a socket

最近我一直在尝试编写一个 client/server 程序来弄乱一些套接字。到目前为止,我已经成功了,但似乎遇到了障碍。对于一些快速的背景信息,我制作了一个可以接受连接的服务器,一旦一切都设置好并建立了与客户端的连接,这段代码就开始执行:

while(1){
        read(newsockfd, &inbuffer, 256);


        std::cout << "Message from client " << inet_ntoa(cli_addr.sin_addr) << " : ";
        for(int i = 0; i < sizeof(inbuffer); i++){
            std::cout << inbuffer[i];

        }
        std::cout << std::endl;

}

现在客户端只需在执行时连接到服务器并写入套接字,然后退出。所以既然发送了一条消息,这个循环应该只运行一次,如果我读到的是正确的,然后等待另一条消息。

但最终发生的是这个循环一遍又一遍地继续,一遍又一遍地打印相同的消息。从我读到的(在这个网站和其他网站上)关于 read() 函数的内容是,在它被调用一次之后,它会等待收到另一条消息。我可能在这里犯了一个愚蠢的错误,但是有什么办法可以让这个 read() 函数等待新消息,而不是一遍又一遍地使用相同的旧消息?或者是否有另一个函数可以替代 read() 来执行我想要的操作?

感谢您的帮助。

您没有检查 read 的 return 值。因此,如果另一端关闭连接或出现错误,您将永远循环输出缓冲区中的任何内容。你可能想要:

while(1){
    int msglen = read(newsockfd, &inbuffer, 256);
    if (msglen <= 0) break;

    std::cout << "Data from client " << inet_ntoa(cli_addr.sin_addr) << " : ";
    for(int i = 0; i < msglen; i++){
        std::cout << inbuffer[i];
    }
    std::cout << std::endl;

}

请注意,我将单词 "message" 更改为 "data"。原因如下:

So since one message was sent, this loop should only run once, and then wait for another message if what I read was correct.

这是不正确的。上面的代码没有任何 "message" 的概念,并且 TCP 不保留应用程序消息边界。所以这不仅是错误的,而且不可能是正确的,因为 "message" 这个词没有任何可能适用于这种情况的含义。 TCP 不会 "glue together" 碰巧在一次发送函数调用中传递的字节。