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

时间:2015-04-08 17:32:02

标签: c++ sockets

我正在使用此服务器代码:

     [...]
     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

那么,我该怎么办?非常感谢你。

2 个答案:

答案 0 :(得分:2)

根据documentation of the POSIX read function

  

如果fildes引用套接字,则read()应等于recv()且不设置标志。

documentation of recv说明以下

  

对于基于流的套接字,例如SOCK_STREAM,应忽略消息边界。在这种情况下,数据一旦可用就应该返回给用户,并且不会丢弃任何数据。

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

答案 1 :(得分:0)

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

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