Skip to content
Advertisement

client stops connecting to server after 2-3 successful connections. socket programming in c

I am trying out simple client-server program using socket programming in c. The program works fine when I execute server first and then client but after two to three successful executions, the client stops connecting to the server. This again starts working if I execute the programs after a certain amount of time.

Client code:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main(){
    int clientSocket,len;
    char buffer[1024];
    struct sockaddr_in sadd;

    clientSocket = socket(PF_INET, SOCK_STREAM, 0);

    sadd.sin_family = AF_INET;
    sadd.sin_port = htons(12345);
    sadd.sin_addr.s_addr = inet_addr("127.0.0.1");
    memset(sadd.sin_zero, '', sizeof sadd.sin_zero);  

    len = sizeof sadd;
    while(connect(clientSocket, (struct sockaddr *) &sadd, len) == -1) {
        sleep(1);
        printf("trying again..n");
    }

    read(clientSocket, buffer, sizeof(buffer));
    printf("Data received: %s",buffer);  

    return 0;
}

Server code:

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main(){
    int defSock, newSock, len;
    char buffer[1024];
    struct sockaddr_in sadd, cadd;


    socklen_t addr_size;

    defSock = socket(PF_INET, SOCK_STREAM, 0);

    sadd.sin_family = AF_INET;
    sadd.sin_port = htons(12345);
    sadd.sin_addr.s_addr = INADDR_ANY;  

    bind(defSock, (struct sockaddr *) &sadd, sizeof(sadd));

    if(listen(defSock,5)==0)
        printf("Listeningn");
    else
        printf("Errorn");

    len = sizeof(cadd);

    newSock = accept(defSock, (struct sockaddr *) &cadd, &len);
    strcpy(buffer,"Hello Worldn");
    int n = write(newSock,buffer,sizeof(buffer));

    close(newSock);

    return 0;
}

Executing client in the terminal multiple times:

[kj@localhost Downloads]$ gcc client.c -o client
client.c: In function ‘main’:
client.c:16:25: warning: implicit declaration of function ‘inet_addr’ [-Wimplicit-function-declaration]
  sadd.sin_addr.s_addr = inet_addr("127.0.0.1");
                         ^
client.c:21:3: warning: implicit declaration of function ‘sleep’ [-Wimplicit-function-declaration]
   sleep(1);
   ^
client.c:25:2: warning: implicit declaration of function ‘read’ [-Wimplicit-function-declaration]
  read(clientSocket, buffer, sizeof(buffer));
  ^
[kj@localhost Downloads]$ ./client 
Data received: Hello World
[kj@localhost Downloads]$ ./client 
trying again..
trying again..
trying again..
trying again..
trying again..
trying again..
trying again..
trying again..
trying again..
^C
[kj@localhost Downloads]$ ./client 
trying again..
trying again..
trying again..
^C
[kj@localhost Downloads]$ ./client 
trying again..
trying again..
trying again..
trying again..
^C
[kj@localhost Downloads]$ 

Simultaneously executing server on another terminal:

[kj@localhost Downloads]$ gcc server.c -o server
server.c: In function ‘main’:
server.c:31:10: warning: implicit declaration of function ‘write’ [-Wimplicit-function-declaration]
  int n = write(newSock,buffer,sizeof(buffer));
          ^
server.c:33:2: warning: implicit declaration of function ‘close’ [-Wimplicit-function-declaration]
  close(newSock);
  ^
[kj@localhost Downloads]$ ./server 
Listening
[kj@localhost Downloads]$ ./server 
Listening
^C
[kj@localhost Downloads]$ ./server 
Listening
^C
[kj@localhost Downloads]$ ./server 
Listening
^C
[kj@localhost Downloads]$ 

Advertisement

Answer

The use of SO_REUSEADDR hides another problem:

Your server is only able to serve one client, and does not cleanly close its listening socket when one client has been served.

To correct this, you should add a while loop in your server in order to allow multiple clients connections.

In your code, I added:

  • One while loop not to stop after the first client connection,
  • One test/perror to stop the server in case of error,
  • One close on listening socket for a clean exit.

This is the code:

/* include */

int main(){

    /* init */

    if(listen(defSock,5)==0)
        printf("Listeningn");
    else
        printf("Errorn");

    len = sizeof(cadd);

    // while they're no error
    while (1)
    {
        // wait for new connection
        newSock = accept(defSock, (struct sockaddr *) &cadd, &len);

        // test if client connection succeded
        if (-1 == newSock)
        {
            // something went wrong: kill the server
            perror("accept()");
            break
        }
        else        
        {
            // say hello
            static const char hello[] = "Hello, world!n";
            int n = write(newSock, hello, sizeof hello - 1); /* -1 to exclude the final '' char */
            if (n < 0)
                perror("write");
            close(newSock);
        }
    }

    // And close the server listening socket
    close(defSock);

    return 0;
}
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement