我有一个非常烦人的问题,我在其他论坛上发现了几次,但找不到合适的解决方案。问题是recv()在连接的最后几个字节上返回0。以下是一些背景信息。
我多次调用send()(小块),并从客户端传输了53个字节。服务器多次调用recv()(4个字节的请求)并读取49个字节,然后返回0(54个字节-49个字节,因此缺少4个字节)。
MSDN和一些论坛写的非阻塞套接字:
MSDN也说:
与SD_SEND或SD_BOTH一起使用closesocket或关机功能 导致在控制通道上发出RELEASE信号。到期 对于ATM使用单独的信号和数据通道的情况, RELEASE信号可能在最后一个 数据到达其目的地,导致该数据丢失。一 可能的解决方案是在最后一个之间编程足够的延迟 发送的数据以及closesocket或关闭功能需要ATM 套接字。
在recv()和send()的示例中认为:http://msdn.microsoft.com/en-us/library/windows/desktop/ms740121(v=vs.85).aspx
但是仍然没有成功,在收到49字节后,我仍然在所有连接的10%中得到一些中断,其中90%的连接成功。有任何想法吗?谢谢。
recv()
仅在您请求一个0字节的缓冲区或另一个对等方已正常断开连接时才返回0。如果您没有收到期望的所有数据,则说明开始时您没有正确读取数据。请使用您的实际代码更新您的问题。
我的猜测是您并没有真正发送您认为正在发送的所有数据。签出:
- 当另一侧关闭连接时,recv()绝对返回= 0
这不是完全正确,在下面的代码中使用无阻塞winsock2 tcp,当没有可用数据时,select返回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”被“破坏了”。