我试图检测连接何时被删除。
通过这种方式,它只会在互联网恢复时检测到连接不再处于活动状态,而在实际丢弃时则不会。
int loop = 1;
long int msConn;
// Main thread
void connect() {
// ...
while (loop) {
if ((sizeBytes = recv(sockfd, buffer, MAX_BUFFER_SIZE - 1, 0)) == -1) {
cout << "Error: connection lost." << endl;
sleep(15);
connect();
return;
}
// Update timestamp
struct timeval tp;
gettimeofday(&tp, NULL);
msConn = tp.tv_sec * 1000 + tp.tv_usec / 1000;
}
}
// Heartbeat thread
void checkConnection() {
for(;;) {
struct timeval tp;
gettimeofday(&tp, NULL);
long int ms = tp.tv_sec * 1000 + tp.tv_usec / 1000;
if (msConn != 0) {
if ((ms - msConn) >= 10000) {
msConn = 0;
close(sockfd);
}
}
sleep(15);
}
}
答案 0 :(得分:2)
recv()
出错时返回-1(例如连接意外丢失), 0表示正常断开连接(您忽略!),&gt; 0表示数据已成功读取。更改循环以处理recv()
返回0时的情况,否则当对等方故意断开连接时,您的循环不会退出:
while (loop) {
sizeBytes = recv(sockfd, buffer, MAX_BUFFER_SIZE - 1, 0);
if (sizeBytes == -1) {
cout << "Error: connection lost." << endl;
close(sockfd);
sleep(15);
return;
}
if (sizeBytes == 0) {
cout << "Connection disconnected by peer." << endl;
close(sockfd);
sleep(15);
return;
}
// Update timestamp
struct timeval tp;
gettimeofday(&tp, NULL);
msConn = tp.tv_sec * 1000 + tp.tv_usec / 1000;
}
话虽如此,如果连接异常丢失,可能需要OS很长时间才能检测到该情况。您正在实现自己的超时以解决此问题,但如果您在阻塞模式下使用套接字(默认行为),则可能需要很长时间才能退出{(1}}(因此可能会阻止您的循环退出)及时)。您可以使用recv()
/ select()
或epoll()
来避免这种情况。