客户端调用 connect() 而服务器不调用 listen()

Client Calling connect() without server calling listen()

我有一个使用套接字的普通服务器和客户端 TCP C 程序。 它在服务器首先启动时完美运行(即服务器调用 listen() 然后等待客户端调用 connect())。

现在,我要实现的是先启动客户端,然后再启动服务器的情况。

客户端应不断尝试连接到服务器。在服务器关闭之前,我知道客户端的 connect() 调用将 return -1;但客户端应继续尝试,直到建立成功连接。

目前在客户端,我正在尝试在 while 循环中调用 connect(),但如果客户端 运行s 时服务器尚未侦听,它将无法工作.

客户端连接代码:

while( 1)
    {
        
        for(int j=0; j<argc-3; j++){
            //sockfd of each server needed to be connect()ed is stored in array all_sock_fd[]

            if ((sender_conn=connect(all_sock_fd[j], (struct sockaddr *)&all_sockaddrs[j],sizeof(struct sockaddr)) == -1)) {
                
                //do nothing if fails
            }
            else{ //if connection successful then create a thread for that connection
                if( pthread_create( &thread_id , NULL ,  you_connect_to_others , (void*) &all_sock_fd[j]) < 0)
                {
                    perror("could not create thread");
                    return 1;
                }
                
            }
        }
}

当服务器在客户端调用 connect() 之前已经 listen()-ing 时,上面的代码工作正常。 但是,如果客户端在服务器之前 运行(即如果服务器在客户端之后 2 秒启动),那么此代码将永远不会连接。

我尝试了 while 循环方法,其中客户端不断尝试调用 connect() 希望当服务器最终调用 listen() 时,将建立连接。

但这不起作用。即使在客户端之后打开服务器,连接也永远不会发生。

我可以使用 select()poll() 吗?如果是,怎么办?

您的代码大部分是正确的。但是,您需要在每次循环迭代时关闭并重新创建套接字(参见 Does socket become unusable after connect() fails?),例如:

for(int j = 0; j < argc-3; j++){
    //sockfd of each server needed to be connect()ed is stored in array all_sock_fd[]
    int sockfd;
    while (1)
    {
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0)
        {
            perror("could not create socket");
            return 1; 
        }

        sender_conn = connect(sockfd, (struct sockaddr *)&all_sockaddrs[j], sizeof(all_sockaddrs[j]));
        if (sender_conn == 0) break;

        // examine errno and decide whether it is reasonable to continue retrying

        close(sockfd);

        //wait a few seconds and try again
        sleep(5);
    }

    //connection successful, create a thread for that connection
    all_sock_fd[j] = sockfd;
    if (pthread_create(&thread_id, NULL, you_connect_to_others, (void*) &all_sock_fd[j]) < 0)
    {
       perror("could not create thread");
       close(all_sock_fd[j]);
       all_sock_fd[j] = -1;
       return 1; 
    }
}