Home > Back-end >  Client Calling connect() without server calling listen()
Client Calling connect() without server calling listen()

Time:03-23

I have a normal server and client TCP C program that uses sockets. It works perfectly when server is started first (i.e. server calls listen() and then waits for client to call connect()).

Now, what I want to implement is a situation where the client is started first, and the server is started at any later time.

The client should keep trying to connect to the server. Until server is OFF, I know that the client's connect() call will return -1; but the client should keep trying until a successful connection is established.

Currently on the client side, I am trying to call connect() in a while loop but it will not work if server isn't already listening when the client runs.

Client connect code:

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;
                }
                
            }
        }
}

The code above works fine when Servers are listen()-ing already before client calls connect(). But if the client is run before the server (i.e. if server starts 2 seconds after client) then this code will never connect.

I tried the while loop approach where the client keeps trying to call connect() hoping that when server finally calls listen(), a connection will be established.

But this does not work. Even when server is turned ON after the client, The connection never happens.

Can I use select() or poll() for this? If so , how?

CodePudding user response:

Your code is mostly correct. However, you need to close and recreate the socket on each loop iteration (see Does socket become unusable after connect() fails?), eg:

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; 
    }
}
  • Related