【问题标题】:Connect to socket leaves connections in TIME_WAIT states连接到套接字使连接处于 TIME_WAIT 状态
【发布时间】:2016-09-04 12:56:59
【问题描述】:

我正在尝试解析主机名,然后打开/关闭与主机的套接字。

下面的代码可以正常工作。我遇到的问题是连接似乎没有正确关闭。我还剩下一堆 TIME_WAITS:

tcp        0      0 192.168.142.139:44475   172.217.23.14:443       TIME_WAIT
tcp        0      0 192.168.142.139:44362   45.79.5.162:80          TIME_WAIT
tcp        0      0 192.168.142.139:44373   45.79.5.162:80          TIME_WAIT
tcp        0      0 192.168.142.139:44461   172.217.23.14:443       TIME_WAIT
tcp        0      0 192.168.142.139:44468   172.217.23.14:443       TIME_WAIT
tcp        0      0 192.168.142.139:44472   172.217.23.14:443       TIME_WAIT
tcp        0      0 192.168.142.139:44474   172.217.23.14:443       TIME_WAIT
tcp        0      0 192.168.142.139:44459   172.217.23.14:443       TIME_WAIT
tcp        0      0 192.168.142.139:44470   172.217.23.14:443       TIME_WAIT
tcp        0      0 192.168.142.139:44463   172.217.23.14:443       TIME_WAIT
tcp        0      0 192.168.142.139:44464   172.217.23.14:443       TIME_WAIT

我并不特别需要向主机发送任何特定的内容,这更像是一般的互联网检查。我也尝试过使用非阻塞连接,然后是选择。结果一样。

  int port = 443;
  char *hostname = "google.com";

  int open_socket(char *ip)
  {
    int error = 0; // Socket error
    struct sockaddr_in address;
    short int sock = -1;
    fd_set fdset;
    struct timeval tv;
    int so_keepalive = 0;

    sock = socket(PF_INET, SOCK_STREAM , 0);
    if (sock < 0)
      return 150;

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr(ip);
    address.sin_port = htons(port);
    /* address.sin_addr.s_addr = INADDR_ANY; */

    FD_ZERO(&fdset);
    FD_SET(sock, &fdset);
    tv.tv_sec =  3;
    tv.tv_usec = 0;

    int yes = 1;
    // setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int));
    // setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
    setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval));
    setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &so_keepalive, sizeof(so_keepalive));

    if (connect(sock, (struct sockaddr *)&address , sizeof(address)) < 0)
      error = 150;

    if (error == 0) {
      char *message = "HELLO";
      if (send(sock , message , strlen(message) , 0) < 0)
        error = 180;

      char server_reply[2000];
      if( recv(sock, server_reply , 2000 , 0) < 0)
        error = 190;
    }

    /* shutdown(sock, SHUT_RDWR); */
    close(sock);
    return error;
  }

  int connection_check()
  {
    struct addrinfo *result;
    struct in_addr addr;

    int error;

    error = getaddrinfo(hostname, NULL, NULL, &result);
    if (error != 0)
    {
      fprintf(stderr, "DNS Lookup Failed: %s\n", gai_strerror(error));
      return 100;
    }

    addr.s_addr = ((struct sockaddr_in *)(result->ai_addr))->sin_addr.s_addr;
    printf("\nUsing %s for internet check\n", inet_ntoa(addr));
    freeaddrinfo(result);
    return(open_socket(inet_ntoa(addr)));
  }

有人可以建议我应该如何正确处理这个问题。

【问题讨论】:

  • 您正确地处理了这个问题:或者至少这里没有问题需要解决。 TIME_WAIT 状态是 TCP 的正常部分。持续几分钟。
  • 好的,我通常担心我没有正确关闭某些东西。我会忽略并继续。谢谢

标签: c sockets


【解决方案1】:

TCP 要求关闭连接的端点进一步阻塞 在同一主机/端口对上的连接,直到没有来自的数据包 该连接仍在网络中。

为了暂时阻止连接,一个端点会保留一份 TCP 指示连接已终止的控制块 (TCB) 最近。这样的连接处于 TIME-WAIT 状态。连接 TIME-WAIT 被移到 CLOSED 并且它们的 TCB 在足够多之后被丢弃 时间已经过去,来自同一连接的所有数据包都已离开 网络。数据包通过到达其中一个离开网络 端点并被拒绝,或以过期的生存时间到达 (TTL) 字段并被删除。

http://www.isi.edu/touch/pubs/infocomm99/infocomm99-web/

【讨论】:

  • 这是答案吗?
  • 如果它对你有帮助,它是,如果不是,它不是;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-08
  • 2018-04-13
  • 1970-01-01
  • 1970-01-01
  • 2016-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多