拔下以太网时没有得到Winsock错误
not getting a Winsock error when ethernet unplugged
我正在开发一个客户端应用程序,该应用程序以一种方式将传感器数据发送到远程服务器。初次登录后,服务器没有返回数据。我的问题是,当以太网断开连接时,例如硬断开连接,即无线链路断开时,我的应用程序在尝试"发送"调用后不会得到错误返回值。我正在使用一个非阻塞套接字实例。线程使用"select"检查每个循环的"recv"。它最终会在"recv"上出错,但在"send"上从未出错。当远程电脑失去互联网连接时,它将导致程序与服务器断开几分钟到几个小时的连接,然后才意识到发生了连接丢失并切换到重新登录服务器。可以做些什么来帮助检测硬断开连接?
void checkConnect(NTRIP& server)
{
//1st check for recv or gracefully closed socket
char databuf[SERIAL_BUFFERSIZE];
fd_set Reader, Writer, Err;
TIMEVAL Timeout;
Timeout.tv_sec = 1; // timeout after 1 seconds
Timeout.tv_usec = 0;
FD_ZERO(&Reader);
FD_ZERO(&Err);
FD_SET(server.socket, &Reader);
FD_SET(server.socket, &Err);
int iResult = select(0, &Reader, NULL, &Err, &Timeout);
if(iResult > 0)
{
if(FD_ISSET(server.socket, &Reader) )
{
int recvBytes = recv(server.socket, databuf, sizeof(databuf), 0);
if(recvBytes == SOCKET_ERROR)
{
cout << "socket error on receive call from server " << WSAGetLastError() << endl;
closesocket(server.socket);
server.connected_IP = false;
}
else if(recvBytes == 0)
{
cout << "server closed the connection gracefully" << endl;
closesocket(server.socket);
server.connected_IP = false;
}
else //>0 bytes were received so read data if needed
{
}
}
if(FD_ISSET(server.socket, &Err))
{
cout << "select returned socket in error state" << endl;
closesocket(server.socket);
server.connected_IP = false;
}
}
else if(iResult == SOCKET_ERROR)
{
cout << "ip thread select socket error " << WSAGetLastError() << endl;
closesocket(server.socket);
server.connected_IP = false;
}
//2nd check hard disconnect if no other data has been sent recently
if(server.connected_IP == true && getTimePrecise() - server.lastDataSendTime > 5.0)
{
char buf1[] = "hello";
cout << "checking send for error" << endl;
iResult = send(server_main.socket, buf1, sizeof(buf1), 0);
if(iResult == SOCKET_ERROR)
{
int lasterror = WSAGetLastError();
if(lasterror == WSAEWOULDBLOCK)
{
cout << "server send WSAEWOULDBLOCK" << endl;
}
if(lasterror != WSAEWOULDBLOCK)
{
cout << "server testing connection send function error " << lasterror << endl;
closesocket(server.socket);
server.connected_IP = false;
}
}
else
{
cout << "sent out " << iResult << " bytes" << endl;
}
server.lastDataSendTime = getTimePrecise();
}
}
在尝试发送内容之前,无法检测到断开连接。您的解决方案如下:
-
您检测到在一段时间内没有收到任何数据,并且要检查连接是否处于活动状态。
-
您可以使用
send
函数将一些数据发送到服务器。它可能是特定于协议的ping数据包,也可能是垃圾。send
函数会立即返回,因为它不等待实际的数据发送。它只填充内部发送缓冲区。 -
您开始等待套接字读取。
-
在等待期间,操作系统会尝试将发送缓冲区中的数据发送到服务器。
-
当操作系统检测到无法将数据传递到服务器时,连接将被标记为错误。
-
现在,调用
recv
和send
函数时会出现错误。
发送超时是系统特定的,可以进行配置。通常,它大约是20秒(Linux)-2分钟(Windows)。这意味着您需要等待很长时间才能收到错误。
注:
-
您也可以打开TCP保持活动机制,但我不建议您这样做。
-
您还可以修改TCP超时间隔。当您希望连接在临时网络断开后仍然有效时,它会很有帮助。
这就是TCP的工作方式和预期工作方式。您将在随后的发送中收到错误,但在断开连接后的第一次发送中永远不会收到错误。在发出错误信号之前,需要克服缓冲、重试和重试超时。
- 错误:10035 Winsock发送
- Winsock错误10022在听
- 致命错误:Winsock:没有这样的文件或目录
- Winsock 400 错误请求,开放性
- Winsock客户端在本地网络上发生错误11004
- 使用 winsock 库发送 GET HTTP 请求时出现 400 错误请求错误
- Winsock 错误 10049 尝试绑定
- C++ WinSock Recv 在接收 0 数据时终止线程而不是返回错误代码
- C++WinSock蓝牙连接-AT命令-收到错误
- 在C++中处理 Winsock 错误的推荐方法是什么?
- Winsock选择错误10038,绑定和侦听成功
- Winsock发送失败,错误为10093
- Winsock send()总是在服务器中返回错误10057
- Winsock重新定义错误
- C++ Winsock 在 bind() 上给出 10038 错误
- 尝试在 dev C++ win7 中编译 winsock 程序 - 错误
- Winsock -> WinRT Windows.Networking.Sockets -- 映射错误代码
- Winsock UDP文件终止错误10040
- Winsock Connect失败,错误为10049
- 拔下以太网时没有得到Winsock错误