挂在connect()

时间:2018-08-23 23:02:27

标签: c sockets network-programming

因此,我有一个尝试与服务器连接的客户端。 ip和端口从配置文件中检索。如果配置文件中的某些内容不正确,我需要程序顺利失败。我使用以下代码连接到服务器

if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1)
{
    perror("client: connect");
    close(sockfd);
    continue;
}

如果用户尝试连接到不接受连接(即不存在)的子网上的服务器,则程序将失败,并显示No route to host。如果程序尝试连接到不在子网上的服务器(即配置错误),则程序会在connect()调用处挂起。我做错了什么?我需要这样做是为了向用户提供有关应用程序失败的反馈。

2 个答案:

答案 0 :(得分:3)

您没有做错任何事情。 TCP是为面对网络问题而设计的可靠性,因此,如果它没有收到对其初始连接请求的响应,则它会重试几次,以防请求或响应在网络中丢失。 Linux上的默认参数导致大约需要一分钟时间才能放弃。然后它将报告失败,并显示 docker run -d --hostname my-rabbit -p 5672:5672 --name some-rabbit rabbitmq:3 错误。

如果您想更快地检测到故障,请参阅C: socket connection timeout

答案 1 :(得分:1)

通常,我们不会在continue语句中使用if,除非if语句在循环中(您未显示)。假设存在外部循环,则这将负责接下来发生的事情..要么继续重新进入if块(以尝试再次连接),要么跳过它。

请注意,您正在sockfd块内关闭if,因此,如果您的循环重新进入if块以进行重试,则它需要首先创建一个新的套接字。

我建议阅读一些客户端和服务器端套接字连接的示例代码,以更好地了解其工作原理http://www.cs.rpi.edu/~moorthy/Courses/os98/Pgms/socket.html

如果所有操作均失败,请在if块周围提供代码,并说明您希望“顺利失败”的方式。一种“突然”失败的方法是将continue语句换成对exit()“-)的调用

编辑:在阅读Barmar的答案和他的评论后,您还需要注意以下几点:

  

如果发起套接字是连接模式,则connect()应该   尝试建立与该地址指定的地址的连接   地址参数。如果无法立即建立连接   并且未为套接字的文件描述符设置O_NONBLOCK,   connect()最多应阻止一个未指定的超时间隔,直到   连接已建立。如果超时时间间隔在   建立连接后,connect()将失败并且连接   尝试应中止。

还..

  

如果无法立即建立连接并且O_NONBLOCK为   为套接字的文件描述符设置时,connect()将失败,并且   将errno设置为[EINPROGRESS],但连接请求不得为   终止,并且连接应异步建立。   随后在同一套接字之前调用connect()   建立连接,将失败并将errno设置为[EALREADY]

当您说“程序挂起”时,您的意思是永久的,或者是一段可能由TCP / IP超时解释的时期。

如果这和Barmar的答案仍然不够,那么将有助于根据建议查看周围的代码,并确定是被阻止还是未被阻止等。