我正在尝试升级我的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套接字库检测网络是否已断开连接?
非常感谢!
答案 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请求之前调整等待的数量,并根据系统要求调整预期响应的时间。
如果您正在使用其他“数据等待”指示,您可以使用异步计时器而不是循环,但想法是相同的...如果您不接收数据,请发送一些请求数据。如果您仍然没有收到数据,请假设存在问题。