Windows 7中带有非阻塞recv的C ++ TCP套接字

时间:2013-10-23 10:07:39

标签: c++ sockets windows-7 tcp nonblocking

我正在尝试升级我的C ++ TCP客户端程序以与Windows 7兼容。该程序设置为使用非阻塞套接字,它适用于Windows XP。但是,当我在Windows 7中运行相同的代码并发现套接字类中的recv函数表现不同时。

当我尝试断开以太网电缆与PC的连接时,Windows XP和Windows 7都检测到系统托盘中的网络已断开连接。然而,

在Windows XP中, recv返回SOCKET_ERROR,WSAGetLastError返回WSAECONNRESET

在Windows 7中, recv返回SOCKET_ERROR但WSAGetLastError返回WSAEWOULDBLOCK

我很好奇为什么socket recv函数仍然认为套接字仍然连接(即返回WSAEWOULDBLOCK)并且只检测到keepalive超时后断开连接。

除了在调用recv函数后检查WSAGetLastError的值之外,还有其他方法可以使用TCP套接字库检测网络是否已断开连接?

非常感谢!

2 个答案:

答案 0 :(得分:1)

我会说Windows 7在这里表现正常,并且XP错误立即对电缆拉动作出反应。 TCP从一开始就意味着具有高度容错能力,特别是在不中断现有连接的情况下允许电缆拉动或路由器中断。

  

还有其他方法[etc]

检测TCP连接中断的最可靠方法是发送。经过足够的缓冲,重试等后,TCP将放弃发送并向send()的调用者发送重置。但它可能需要一段时间,还有几个电话。

答案 1 :(得分:0)

您可能正在使用循环select来等待数据,在这种情况下,伪代码的想法是这样的:

bool ping_outstanding = false;
while (running) {
   waitForDataMaxSeconds(5);
   if (dataAvailable()) {
      // all is good
      ping_outstanding = false;
      getData(); // Could be normal data or a ping response
   }
   else if ( !ping_outstanding ) {
      ping_outstanding = true;
      sendPing();
      // I should get data in response to this
   }
   else {
      // I've got connection trouble!
   }
}

当然,您可以在发送ping请求之前调整等待的数量,并根据系统要求调整预期响应的时间。

如果您正在使用其他“数据等待”指示,您可以使用异步计时器而不是循环,但想法是相同的...如果您不接收数据,请发送一些请求数据。如果您仍然没有收到数据,请假设存在问题。