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