呼叫连接需要花费太多时间

时间:2016-11-18 07:03:07

标签: c sockets unix ip

我的任务是检查IP是否存在。所以我按照这个link修改了代码,如下所示......

int isServerAlive(const char* serverAdd)
{
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port   = htons(65432);  // Could be anything.
    inet_pton(AF_INET, serverAdd, &sin.sin_addr);

    if (connect(sockfd, (struct sockaddr *) &sin, sizeof(sin)) == -1)
    {
        // The two main errors you get if the host is dead are ENETUNREACH and ETIMEDOUT.
        if (errno == ENETUNREACH || errno == ETIMEDOUT)
        {
            printf("Error connecting %s: %d (%s)\n",serverAdd, errno, strerror(errno));
            return FAILURE;
        }
    }
    return SUCCESS;
}

当我尝试执行此代码时,连接通话花费了太多时间。

  • 我在这里做错了吗?
  • 还有其他更好的方法可以检查IP是否存在吗?

提前致谢。

2 个答案:

答案 0 :(得分:1)

如果连接尝试超时,则网络堆栈将再次尝试几次。等待一段时间,不幸的是重试需要时间。

基本上有两种解决方法:

  1. 使用非阻塞套接字。然后connect调用返回有效连接。它会返回错误,errno设置为EINPROGRESS。如connect手册页中所述,您可以使用例如select查看套接字是否可写,以便知道连接尝试已完成,并且您可以获得状态。

  2. 第二种解决方案是使用线程。然后,当主线程执行其他操作时,连接尝试可以在后台运行。

答案 1 :(得分:1)

如果你知道服务器会响应ping,你肯定应该使用 ping 来进行检测。假设您的服务器位于代理或NAT之后,这很容易使您的SYN检测失败。

在Linux环境中,ping检测机制应该是这样的:

system("ping xx.xx.xx.xx -c 3 -i 1 -W 3 -q > /tmp/ping-xx.xx.xx.xx.log &");

6秒后,您可以打开文件,并解析ping结果:

  

传输3个数据包,0个接收, 100%丢包,时间2039ms

Note: 
              -c 3: only issue 3 ping packets
              -i 1: send packets at 1 second interval
              -W 3: wait response up to 3 seconds, so the total time should no more than 3 + 3 = 6 seconds
              -q: suppress no needed information.

这些ping参数仅作为示例服务器,您应该根据您的真实环境对它们进行自定义。