4

im using socket in c and got success on send/recv. however, the problem is when my server crashes, the client has to reconnect the server (server runs after some time). so here what i did:

  1. create a socket
  2. connect
  3. recv/send
    • if recv size == 0 go to step 2.

this algorithm is not working for me. is there any ideas?

code:

int initSocket(char *servIP, unsigned short serverPort)
{
    portNum = serverPort;
    ipAddr = servIP;
                            /* Socket descriptor */
    struct sockaddr_in echoServAddr; /* Echo server address */

    if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    {
        printf("socket() failed");
        bConnected = -1;
        return -1;
    }

    /* Construct the server address structure */
    memset(&echoServAddr, 0, sizeof(echoServAddr));     /* Zero out structure */
    echoServAddr.sin_family      = AF_INET;             /* Internet address family */
    echoServAddr.sin_addr.s_addr = inet_addr(ipAddr);   /* Server IP address */
    echoServAddr.sin_port        = htons(portNum);      /* Server port */

    struct timeval timeout;
    timeout.tv_sec = 0;
    timeout.tv_usec = 20000;

    if (setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
        error("setsockopt failed\n");

    /*if (setsockopt (sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
         error("setsockopt failed\n");
    */
    /* Establish the connection to the echo server */
    if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
    {
        printf("connect() failed\n");
        bConnected = -1;
        //close(sock);
        return -1;
    }

    bConnected = 0;
    return 0;
}




--------------- if server crashes ------------
if(recv_size == 0)
            {
            // server crashed
                while(initSocket(ipAddr, portNum) < 0)
                {
                    printf("IP : %s\v", ipAddr);
                    printf("Port : %d\v", portNum);                 
                }

            } 
-----------------------------
  • 3
    What is happening that you are saying "it's not working" ... is an error returned via `errno`, or you hang, etc.? – Jason May 10 '12 at 12:53
  • possible duplicate of [Using SO_REUSEADDR - What happens to previously open socket?](http://stackoverflow.com/questions/775638/using-so-reuseaddr-what-happens-to-previously-open-socket) – Ed Heal May 10 '12 at 13:07
  • You set your socket on a 20 msec timeout. What happens if the client doesn't receive anything from the server before the timeout? Won't it think the server has crashed again? – Klas Lindbäck May 10 '12 at 13:21
  • thx for trying to help guys. Jason, let's look at this scenario, client connects to running server. Suddenly server crashes and client cannot send/recv anything. So, server runs again(let's say somebody loads it again) client tries to reconnect (client didnot crash yet.) i did above steps and create socket again but nothing happened. programs just slept. –  May 11 '12 at 00:04

1 Answers1

7
  1. create a socket
  2. connect
  3. recv/send if recv size == 0 go to step 2.

You cannot re-connect a TCP socket, you have to create a new one. You'd also want to handle the case where recv or send errors.

So this have to be:

  1. create a socket
  2. connect
  3. recv/send if recv returns <= 0 or send returns -1 (and it's not a timeout): close socket, goto step 1

Though, it seems your code already does all these steps, and not just repeating step 2 and 3, so it's a bit unclear what's the actual problem you are observing.

In addition, your initSocket() code does not close() the socket when connect() fails, so you'll easily leak sockets and run out of file descriptors in less than a second once the server fails, you have to close() the socket you just created if you're not going to use it.

nos
  • 223,662
  • 58
  • 417
  • 506
  • hi nos, i did try your way before and came with same result. i could not reconnect yet. –  May 11 '12 at 00:14
  • @mashhur Well, are you sure your server is up and running again, and really listening on the socket ? (You likely at least have to use SO_REUSEADDR on the server side, otherwise you'll have to wait several minutes before the server is able to bind to the same local port again.) Also you need to describe clearly what the actual problem is, that is, what is happpening, what should happen, what have you done ? – nos May 11 '12 at 06:35