title: C++ tcp socket connection retry method
body: <p>After developing a sample client server application which can exchange some data, I'm trying to implement the retry mechanism into it. Currently my application is following below protocol: </p>
  
  <ol>
  <li>Client connects to server (non blocking mode) with 3 secs timeout and with 2 reties.</li>
  <li>Start sending data from client with fixed length. Send has some error checking whether it is sending the complete data or not.  </li>
  <li>Receive response (timeout: 3secs) from server and verify that. If incorrect response received, re-send the data and wait for response. Repeat this for two times if failed. </li>
  </ol>
  
  <p>For the above implementation code sections look likes something below:</p>
  
  <ol>
  <li>connect() and select() for opening connection</li>
  <li>select() and send() for data send</li>
  <li>select() and recv() for data receiving</li>
  </ol>
  
  <p>Now I'm making the retries based on return types of the socket functions, and if send() or recv() fails I'm retring the same methods. But not recalling connect(). </p>
  
  <p>I tested the thing by restarting the server in between the data transfer, and as a result client fails to communicate with the server and it quits after several retries, I believe this is happening as because there is no connect() call on retry methods. </p>
  
  <p>Any suggestions?</p>
  
  <p>Example code for receiving socket data</p>
  
  <pre><code>bool CTCPCommunication::ReceiveSocketData(char* pchBuff, int iBuffLen)
  {
    bool bReturn = true;
  
    //check whether the socket is ready to receive
    fd_set stRead;
    FD_ZERO(&amp;stRead);
    FD_SET(m_hSocket, &amp;stRead);
    int iRet = select(0, &amp;stRead, NULL, NULL, &amp;m_stTimeout);
  
    //if socket is not ready this line will be hit after 3 sec timeout and go to the end
    //if it is ready control will go inside the read loop and reads data until data ends or
    //socket error is getting triggered continuously for more than 3 secs.
    if ((iRet &gt; 0) &amp;&amp; (FD_ISSET(m_hSocket, &amp;stRead)))
    {
      DWORD dwStartTime = GetTickCount();
      DWORD dwCurrentTime = 0;
  
      while ((iBuffLen-1) &gt; 0)
      {
        int iRcvLen = recv(m_hSocket, pchBuff, iBuffLen-1, 0);
        dwCurrentTime = GetTickCount();
  
        //receive failed due to socket error
        if (iRcvLen == SOCKET_ERROR)
        {
          if((dwCurrentTime - dwStartTime) &gt;= SOCK_TIMEOUT_SECONDS * 1000)
          {
            WRITELOG("Call to socket API 'recv' failed after 3 secs continuous retries, error: %d", WSAGetLastError());
            bReturn = false;
            break;
          }
        }
        //connection closed by remote host
        else if (iRcvLen == 0)
        {
          WRITELOG("recv() returned zero - time to do something: %d", WSAGetLastError());
          break;
        }
  
        pchBuff  += iRcvLen;
        iBuffLen -= iRcvLen;
      }
    }
    else
    {
      WRITELOG("Call to API 'select' failed inside 'ReceiveSocketData', error: %d", WSAGetLastError());
      bReturn = false;
    }
  
    return bReturn;
  }
  </code></pre>