C++ C++;Server recv()命令并不总是从客户端接收send()

C++ C++;Server recv()命令并不总是从客户端接收send(),c++,tcp,server,client,C++,Tcp,Server,Client,我有一个连接到客户端并执行以下通信的服务器: void通信(承诺和除法、承诺和结果、int-sockt、长数字、长素数){ 发送(sockt,编号); 发送(sockt,prime); 长div=接收(sockt); 长res=接收(sockt); 分区。设置_值(div); 结果:设置_值(res); } 无效发送(int sockt,长编号){ 字符串数字字符串; stringstream和strstream; strstream>numberString; cout在void send(i

我有一个连接到客户端并执行以下通信的服务器:

void通信(承诺和除法、承诺和结果、int-sockt、长数字、长素数){
发送(sockt,编号);
发送(sockt,prime);
长div=接收(sockt);
长res=接收(sockt);
分区。设置_值(div);
结果:设置_值(res);
}
无效发送(int sockt,长编号){
字符串数字字符串;
stringstream和strstream;
strstream>numberString;
cout在
void send(int sockt,long number)
中,您对
write()
的调用出现故障,原因如下:

  • sizeof numberString
    是要发送的错误字节数。这是
    string
    类的编译时大小,而不是它指向的字符数据的运行时字节大小

  • 您没有以任何方式对发送的数据进行定界,以使接收方知道数据何时结束。发送可变长度数据时,必须在发送数据之前发送数据长度,或者在数据之后发送唯一的终止符

  • 您没有考虑
    write()
    发送的字节数可能少于请求的字节数。您必须在循环中调用它,直到所需的所有字节都已完全发送

同样,在
long receive(int sockt)
中,您也会遇到与
recv()
相关的类似问题。您只调用了它一次,而不考虑发送的数据的大小。您忽略了它的返回值,以了解实际读取了多少字节

您需要更像以下内容的内容:

void发送(int-sockt,长数字){
ostringstream oss;

oss我怀疑如果您使用的是tcp,那么在接收时,您可能已经收到了超过上一次发送结束的数据包(因为在tcp中,您将在流中接收数据包,因此您没有消息边界)。解决此问题的一种方法是使用恒定的消息大小(例如:使用一些固定大小的int,而不是使用asciiz),或者,您可以每字节接收一个字节,并将0x00视为tbe消息的结尾。您几乎可以肯定在一次接收中同时接收两次发送。此代码还存在其他一些问题,例如使用
sizeof'而不是
strlen()`。太宽。假设我将发送的字符串标准化为10个字符长,您将如何修改我的接收方法以确保我始终接收10个字符长的字符串?将缓冲区大小设置为10字节对我不起作用。请提供10个字符的缓冲区并使用MSG_WAITALL。谢谢!这非常有效,我没有想到分隔符!
Sending: 344486269
Sending: 7
Received: 0
Received: 344486269
Received: 7
Sending: 0
Sending: 344486269