我有一个非常恼人的问题,我发现了好几次在其他论坛,但我找不到一个适当的解决办法。问题是recv()在连接的最后几个字节上返回0。以下是一些背景资料。
我多次调用send() (小块),并从客户端传输53个字节。服务器多次调用recv() (4字节请求)并读取49个字节,然后返回0 (54 bytes - 49 Bytes,因此缺少4个字节)。
MSDN和一些论坛为非阻塞套接字编写:
MSDN还说:
使用SD_SEND或SD_BOTH的密闭或关机函数将在控制通道上发送释放信号。由于ATM使用了单独的信号和数据信道,释放信号有可能在最后一个数据到达其目的地之前到达远程端,从而导致该数据的丢失。一种可能的解决方案是在最后发送的数据与关机或关机函数调用ATM套接字之间设定足够的延迟。
这在recv()和send():http://msdn.microsoft.com/en-us/library/windows/desktop/ms740121(v=vs.85).aspx的例子中得到了考虑。
但是仍然没有成功,在49 Byte被接收后,我仍然在10%的连接中被中断,90%的连接成功。有什么想法吗?谢谢。
发布于 2012-05-10 01:42:25
只有当请求0字节缓冲区或另一个对等点已优雅地断开连接时,recv()才返回0。如果您没有接收到所有您期望的数据,那么首先您将无法正确地读取数据。请用您的实际代码更新您的问题。
发布于 2013-06-20 13:40:26
我的猜测是,你并没有真正发送所有你认为你正在发送的数据。查看:
留恋页
发布于 2020-06-17 10:03:51
这不是完全正确的,在以下使用非阻塞winsock2 tcp的代码中,当没有可用的数据时,选择返回1和recv返回0,就像WSAGetLastError()一样。
fd_set test = {1, socket};
const timeval timeout = {0, 0};
if (!::select(0, &test, nullptr, nullptr, &timeout)) return 0;
int done = ::recv(socket, buffer, 1, 0);即使在另一端呼吁:
::shutdown(socket, SD_BOTH);
::closesocket(socket);然后就结束了。通信如预期的那样工作,它就是::recv,似乎“坏了”。
https://stackoverflow.com/questions/10526382
复制相似问题