检测连接是否已断开

时间:2014-12-22 18:49:37

标签: c++ c++11 tcp-ip

我试图检测连接何时被删除。

通过这种方式,它只会在互联网恢复时检测到连接不再处于活动状态,而在实际丢弃时则不会。

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);
  }
}

1 个答案:

答案 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()来避免这种情况。