【问题标题】:How to implement socket connect() when the server is not running?服务器未运行时如何实现socket connect()?
【发布时间】:2023-01-08 09:11:43
【问题描述】:

如果在我调用此函数之前服务器正在运行,则以下 TCP/IP 客户端代码将按预期工作。如果服务器没有运行,connect() 立即返回并打印 errno = 111, connection refused。我最终在一个无限的 while 循环中调用 connect(),调用之间有 1 秒的延迟。当服务器启动时,代码连接并退出循环。问:connect() 在阻塞模式下应该如何工作?如果是这样,有没有办法配置connect()等到服务器运行后再返回?

int socket_connect(const char *host, int port, int timeout)
{
    struct sockaddr_in sa;
    struct hostent *hp;
    int sockfd = -1;
    
    hp = gethostbyname(host);
    if (hp == NULL)
    {
        return -1;
    }
    
    sa.sin_family = AF_INET;
    sa.sin_port = htons(port);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    int status = connect(sockfd, (struct sockaddr *)&sa, sizeof(sa));
    if (status != 0)
    {
        close(sockfd);
        printf("errno = %d\n",errno);
        return -2;
    }
    ...

【问题讨论】:

  • 是的,这就是它应该的工作方式。它没有内置的方法来等待服务器自动启动
  • connect 尝试“连接”到指定的主机。它只做一件事,导致成功或失败。由用户决定下一步要做什么。要么尝试重复连接过程进行有限次数的尝试,要么显示一条错误消息,表明服务器似乎已关闭(稍后再试)。

标签: c sockets tcp


【解决方案1】:

connect 有一个任务——建立与服务器应用程序的连接。该应用程序应该正在运行并且服务器系统应该可以访问,connect 才能成功。 connect 只是在内部执行TCP handshake,即它发送一个 SYN 数据包并等待服务器的 SYN+ACK。

如果服务器应用程序正在运行并且可以访问(即没有连接丢失或防火墙阻止连接),则服务器系统将使用 SYN+ACK 快速响应,connect 将在短时间内成功。

如果服务器应用程序未运行,则服务器系统将明确拒绝连接尝试 - 导致 connect 返回“连接被拒绝”。如果有防火墙明确拒绝连接或服务器资源不足,例如服务器套接字的listen队列已满,也会出现这种情况。

相反,如果连接丢失,或者如果有防火墙会在数据包到达服务器系统之前通过简单地丢弃数据包来阻止连接尝试,那么 connect 将在内部尝试通过以下方式到达服务器反复重试发送 SYN 以获得响应。一段时间后connect 将放弃并认为连接尝试因“超时”而失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 2012-05-20
    相关资源
    最近更新 更多