如何正确读取套接字消息(C++)

How to properly read from a socket message (C++)

本文关键字:C++ 消息 套接字 何正确 读取      更新时间:2023-10-16

我正在使用以下服务器代码:

     [...]
     while(1){
       bzero(buffer,256);
       n = read(newsockfd,buffer,255);
       if (n < 0) error("ERROR reading from socket");
       cout << "Message " << buffer << n << endl;
     }
     [...]

在客户端,我有(这是Java):

out.writeUTF("MOVE");

这条线重复了好几次。但是,当我这样做时,我得到的输出是:

Message 6

所以n是正确的,但是缓冲区是空的。

我也试过:

out.writeBytes("MOVE");

有时我会得到这个:

Message MOVE4

但有时我会得到这个:

Message M1
Message O1
Message V1
Message E1

那么,我能做什么呢?非常感谢。

根据POSIX读取函数的文档:

如果filtes引用了一个套接字,那么read()应等效于recv(),不设置任何标志。

recv的文件显示以下

对于基于流的套接字,如SOCK_stream,应忽略消息边界。在这种情况下,数据一旦可用,应立即返回给用户,不得丢弃任何数据。

因此,您应该准备好接收不完整的数据(在一次调用读取之后)或使用基于消息的套接字。处理不完整数据的可能方法是传递消息大小或使用特殊值(如NULChar)来标记消息结束。

第一个示例将写入字符串的长度写为实际字符串前面的16位数字。字符串短于256个字符,因此第一个字节为0x00。您需要调整在服务器端读取消息的方式。有关更多信息,请参阅此。

在第二个示例中,您的问题是不能保证在一个缓冲区中接收所有4个字符。在我看来,最好用一个空字节和缓冲区来完成发送的字符串,直到收到这个字节。