0

I have a system where two machines are connected, and send/receive information to each other. One of the servers sends RTP voice packets using RTSP protocol to the other one. I should implement an edge case, and it requires the following;

When the server goes down/crashes, socket connection is lost. I should create and connect a new socket when the server is available. In this regard, I remove the existing socket, create a new one ( with a new file descriptor ). But it does not connect to the server even if it is available..

 static int socket_new_try_connect( struct rtsp_session *s )
 {
   int flags;
   int res = -1;
   socklen_t slen;

   struct hostent *he;
   struct ast_hostent h;

   while( res < 0 )
   {
    sleep(2);
    if ((he=ast_gethostbyname("10.1.1.6", &h)) == NULL) {
            log("socket_new_try_connect::ast_gethostbyname ERROR !\n");
            continue;
    }

    memset(&s->sin, 0, sizeof(s->sin));
    s->sin.sin_family = AF_INET;
    s->sin.sin_port = htons(8554);
    memmove(&s->sin.sin_addr, he->h_addr, sizeof(s->sin.sin_addr));

    /* socket */
    s->sock = socket(AF_INET, SOCK_STREAM, 0);
    if (s->sock < 0) {
            log("socket_new_try_connect::Unable to create RTSP session socket\n");
            continue;
    }

    log("socket_new_try_connect::new RTSP socket is created. \n");

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

    /*if(setsockopt(s->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&timeout, sizeof(timeout)) < 0){
        perror("setsockopt() SO_REUSEADDR");
        close(s->sock);
        continue;
    }*/

    if(setsockopt(s->sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0){
      log(LOG_ERROR, "setsockopt, EXIT FAILURE!\n");
          perror("setsockopt()");
          close(s);
          continue;
    }

if(setsockopt(s->sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0){
        perror("setsockopt()");
        close(s);
        continue;
    }

    flags = fcntl(s->sock, F_GETFL);
    fcntl(s->sock, F_SETFL, flags | O_NONBLOCK);
      while(1)
      {
    res = connect(s->sock, (struct sockaddr *)&s->sin, sizeof(s->sin));
    log(LOG_NOTICE, "socket_new_try_connect::connect RESULT : %d \n",res);

    if(res < 0 && errno != EINPROGRESS) {
            sleep(1);
            continue;
    }
    else if( res < 0 )
    {
        log("socket_new_try_connect::Cannot connect to RTSP recording server. Error :%s\n", strerror(errno));
        close(s->sock);
        break;
    }
    else
    {
         log("socket_new:: SOCKET CONNECT IS SUCCESSFULL ! RESULT : %d \n",res);
         return 1;
     }
      }
   }
   return 1;

}

With the code above, I am getting "Operation in progress" error. I also saved the messages when the server is available again after getting crashed;

tcp messages

Could you please help me to elaborate the problem ?

  • 2
    You might need `SO_REUSEADDR`. – Steve Summit Jul 13 '18 at 15:09
  • A possible duplicate of [this post](https://stackoverflow.com/questions/16211018/how-to-reconnect-the-clients-to-server) and [this post](https://stackoverflow.com/questions/10534399/re-connection-using-socket-in-c?rq=1) –  Jul 13 '18 at 16:00
  • I am getting "Operation now in progress" error while sending connect request. – Cranberriess_ Jul 17 '18 at 15:33
  • You set the socket to *non-blocking* mode, so this is normal. Use `poll(2)` or `select(2)` to wait for it to finish connecting (or use regular blocking `connect(2)`). – Nikolai Fetissov Jul 17 '18 at 15:56

0 Answers0