title: Reading socket: EAGAIN: Resource temporarily unavailable
body: <p>I have created a socket in C++ and I needed it to have certain connection timeout. So that's what is happening:</p>
  
  <ul>
  <li>Create socket</li>
  <li>Make it NON_BLOCKING</li>
  <li>Call connect</li>
  <li>It returns -1 and errno EINPROGRESS as expected</li>
  <li>Call select</li>
  <li>Returns >0, so connection has been made</li>
  <li>Make the socket BLOCKING again</li>
  </ul>
  
  <p>Code for this part is the following:</p>
  
  <pre><code>bool mastControl::prepareSocket(char * address, int port, int * sockfd) {
  
      struct sockaddr_in serv_addr;
      struct timeval timeout = {0,100000};
      struct timeval connTimeout;
      struct hostent * server = NULL;
      fd_set socketSet;
      socklen_t lon;
      int sockOpt = 0;
      long socketFlags = 0;
      int buffersize = 8;
      int res = 0;
      int connectReturn = 0;
      const int WAIT_TO_RECONN = 15;
  
      server = gethostbyname(address);
      *sockfd = socket(AF_INET, SOCK_STREAM, 0);
  
      if (*sockfd &lt; 0) {
          qDebug()&lt;&lt;"Impossible to open socket: "&lt;&lt;strerror(errno);
          return false;
      }
  
      if (server == NULL) {
          qDebug()&lt;&lt;"No such host: "&lt;&lt;strerror(h_errno);
          return false;
      }
  
      // Initializating server direction struct:
      bzero((char *) &amp;serv_addr, sizeof(serv_addr));
      serv_addr.sin_family = AF_INET;
      bcopy((char *)server-&gt;h_addr,
            (char *)&amp;serv_addr.sin_addr.s_addr,
            server-&gt;h_length);
      serv_addr.sin_port = htons(port);
  
      // Making socked non-blocking in order to set a timeout value for connection:
      if((socketFlags = fcntl(*sockfd, F_GETFL, NULL)) &lt; 0){
          qDebug()&lt;&lt;"Impossible to retrieve sockets descriptor flags "&lt;&lt;strerror(errno);
          return false;
      }
      socketFlags |= O_NONBLOCK;
      if(fcntl(*sockfd, F_SETFL, socketFlags) &lt;0){
          qDebug()&lt;&lt;"Impossible to update sockets descriptor flags: "&lt;&lt;strerror(errno);
          return false;
      }
  
      connectReturn = connect(*sockfd,(struct sockaddr *) &amp;serv_addr,sizeof(serv_addr));
      if(connectReturn &lt; 0){
          if(errno == EINPROGRESS){
              do{
                  // Establishing a 15 seconds timeout:
                  connTimeout.tv_sec = 15;
                  connTimeout.tv_usec = 0;
                  FD_ZERO(&amp;socketSet);    // Initialising set of sockets as an empty set
                  FD_SET(*sockfd, &amp;socketSet);    // Adding socket to set
                  connectReturn = select(*sockfd+1, NULL, &amp;socketSet, NULL, &amp;connTimeout);
                  if(connectReturn&lt;0 &amp;&amp; errno!=EINTR){ // Error in select
                      qDebug()&lt;&lt;"Connection error in select function: "&lt;&lt;strerror(errno);
                      return false;
                  }
                  else if(connectReturn&gt;0){ // Socket selected for writing
                      lon = sizeof(int);
                      if(getsockopt(*sockfd, SOL_SOCKET, SO_ERROR, (void*)(&amp;sockOpt), &amp;lon) &lt;0){
                          qDebug()&lt;&lt;"Unnable to get socket options: "&lt;&lt;strerror(errno);
                          return false;
                      }
                      // Checking the value returned:
                      if(sockOpt){
                          qDebug()&lt;&lt;"Error in delayed connection: "&lt;&lt;strerror(errno);
                          return false;
                      }
                      break;
                  }
                  else{ // Timeout
                      qDebug()&lt;&lt;"Connection timeout exceeded: "&lt;&lt;strerror(errno);
                      return false;
                  }
              } while (1);
          }
          else{
              qDebug()&lt;&lt;"Connection error: "&lt;&lt;strerror(errno);
              sleep(WAIT_TO_RECONN); // Wait 15 seconds
              return false;
          }
      }
  
      //Connected
  
      // Must set the socket as blocking again:
      if((socketFlags = fcntl(*sockfd, F_GETFL, NULL)) &lt; 0){
          qDebug()&lt;&lt;"Impossible to retrieve sockets descriptor flags "&lt;&lt;strerror(errno);
          return false;
      }
      socketFlags &amp;= (~O_NONBLOCK);
      if(fcntl(*sockfd, F_SETFL, socketFlags) &lt;0){
          qDebug()&lt;&lt;"Impossible to update sockets descriptor flags "&lt;&lt;strerror(errno);
          return false;
      }
  
      if (setsockopt (*sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&amp;timeout,
                      sizeof(timeout)) &lt; 0) {
          qDebug()&lt;&lt; "ERR  - setsockopt failed";
          return false;
      }
  
      if (setsockopt (*sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&amp;timeout,
                      sizeof(timeout)) &lt; 0) {
          qDebug()&lt;&lt; "ERR  - setsockopt failed";
          return false;
      }
      if ((res = setsockopt (*sockfd, SOL_SOCKET, SO_SNDBUF, &amp;buffersize,
                             sizeof(buffersize))) == -1) {
          qDebug()&lt;&lt; "ERR  - setsockopt failed (SO_SNDBUF) = " &lt;&lt; res;
          return false;
      }
      //Socket Ready
  
      return true;
  }
  </code></pre>
  
  <p>That works ok. But then I have a loop where I'm calling a function which checks if there is a new packet received to read:</p>
  
  <pre><code>bool mastControl::findPacket(int sockfd, st_messageMastToPc * messageReceived, bool * connected) {
  
      int n = 0;
      bool messageFound = false;
      char * buffer = (char *) messageReceived;
      unsigned int pos = 0;
  
      while ( ((n = read(sockfd, &amp;(buffer[pos]), 1)) &gt; 0) and not messageFound) {
  
          //qDebug()  &lt;&lt; "read output " &lt;&lt; n;
          if (n == 1) {
              pos++;
  
              if ( (pos == 1) &amp;&amp; (buffer[0] == 2)) {
                  // Some stuff...
              } else if ( (pos == 2) &amp;&amp; (buffer[1] == 2) ) {
                  // Some stuff...
              } else if (pos &gt;= uiMessageMastToPcSize) {
                  messageFound = true;
                  //Complete message received
              } else if (pos &lt; 2) {
                  // Reseting pos
                  pos = 0;
              }
          }
      }
  
      if (n &lt; 0){
          qDebug()&lt;&lt; "Disconnected. Reason #" &lt;&lt; errno &lt;&lt; ": " &lt;&lt; strerror(errno);
          *connected = false;
      }
  
      return messageFound;
  }
  </code></pre>
  
  <p>Read function is giving EAGAIN as errno, which means "Resource temporarily unavailable". Then I'm supposing I am disconnected, and since boolean connected is now false, in the loop I will be trying to reconnect creating the socket again, ans so on.</p>
  
  <p>So, in the first place I don't know why I'm receiving this error.</p>
  
  <p>In the second place, I don't know if I am disconnected at all, or it's me the one who is disconnecting when creating the new socket after this error.</p>
  
  <p>Any help?</p>