首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >recv()返回0

recv()返回0
EN

Stack Overflow用户
提问于 2012-05-10 01:26:46
回答 3查看 36.7K关注 0票数 7

我有一个非常恼人的问题,我发现了好几次在其他论坛,但我找不到一个适当的解决办法。问题是recv()在连接的最后几个字节上返回0。以下是一些背景资料。

  • 两个应用程序(客户机/服务器)都运行在同一台计算机上。
  • 两个(客户机/服务器)套接字都是非阻塞的。
  • 传输的数据大小为53个字节。
  • 在执行最后一次send()/recv()时,(客户机/服务器)都会调用关机和关闭。
  • 我也试过用SO_LINGER和10秒,也没有成功

我多次调用send() (小块),并从客户端传输53个字节。服务器多次调用recv() (4字节请求)并读取49个字节,然后返回0 (54 bytes - 49 Bytes,因此缺少4个字节)。

MSDN和一些论坛为非阻塞套接字编写:

  • 对于错误,recv()肯定返回<0,并设置errno / WSAGetLastError。
  • 当另一方关闭连接时,recv()肯定返回=0
  • 读取数据时,recv()肯定会返回>0

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%的连接成功。有什么想法吗?谢谢。

EN

回答 3

Stack Overflow用户

发布于 2012-05-10 01:42:25

只有当请求0字节缓冲区或另一个对等点已优雅地断开连接时,recv()才返回0。如果您没有接收到所有您期望的数据,那么首先您将无法正确地读取数据。请用您的实际代码更新您的问题。

票数 17
EN

Stack Overflow用户

发布于 2013-06-20 13:40:26

我的猜测是,你并没有真正发送所有你认为你正在发送的数据。查看:

留恋页

票数 0
EN

Stack Overflow用户

发布于 2020-06-17 10:03:51

  • 当另一方关闭连接时,recv()肯定返回=0

这不是完全正确的,在以下使用非阻塞winsock2 tcp的代码中,当没有可用的数据时,选择返回1和recv返回0,就像WSAGetLastError()一样。

代码语言:javascript
复制
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);

即使在另一端呼吁:

代码语言:javascript
复制
::shutdown(socket, SD_BOTH);
::closesocket(socket);

然后就结束了。通信如预期的那样工作,它就是::recv,似乎“坏了”。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10526382

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档