title: C# synchronous TCP client socket unexplained missing data
body: <p>I'm using TCP over an unreliable mobile data connection, which may drop packets due to interference or whatever may be going wrong with the signal strength. </p>
  
  <p>What complicates matters is that I'm using Modbus TCP and the mobile router on the other end converts this into Modbus RTU (Serial) in order to communicate with a serial based device (slave).</p>
  
  <p>Furthermore, whenever a read request is sent to the serial device its internal pointer will be incremented to the next chunk of data as soon as the response has been sent. The serial device will have no idea whether the mobile connection is still OK; if the response does not make it all the way back to the server it will already have incremented its internal pointer anyway.</p>
  
  <p>In other words take the following scenario:</p>
  
  <ol>
  <li>Server sends modbus read request over TCP.</li>
  <li>Router receives request and passes it to serial device.</li>
  <li>Serial device responds to router.</li>
  <li>Serial device increments data pointer.</li>
  <li>Router fails to send TCP packet back to server.</li>
  <li>Server sends read request again.</li>
  <li>Serial device responds to router.</li>
  <li>Serial device increments data pointer.</li>
  <li>Router send data back to server successfully.</li>
  </ol>
  
  <p>In the above scenario you will see that the problem in step 5 causes a whole data chunk to be missed, because the serial device has no idea that the previous read operation actually failed. It has already moved on to the next chunk! Normally what I would do is detect this problem and use the "request previous data chunk" operation to re-request the previously missed data chunk from the serial device.</p>
  
  <p>Here is my problem: I'm not getting any exceptions or errors from the TCP code even though I have everything enclosed in a SystemException try-catch block and I'm checking the return value.</p>
  
  <p>I looked through my log file carefully and noticed that the time between a request and a response is about 1 second, however at the time of the suspected missed data chunk, the time gap was between 2 and 3 seconds. This would suggest that a send occured, but no data was received so it tried again. But of course when it tried again, the serial device would have already incremented its data pointer to the next set of data.</p>
  
  <p>For some reason the serial device received the read request, however the data never made it back to the server.</p>
  
  <p>I'm not an expert on TCP/IP, so does anyone out there know what could have happened? Is it possible for TCP to resend packets "under the hood" without causing exceptions and without me knowing? </p>
  
  <p>In my code I'm simply doing something like this:</p>
  
  <pre><code>_log.Debug(string.Format("[{0}]: Sending sync response ({1}).", 
      this._IP.ToString(), CoreUtils.PayloadToString(write_data)));
  
  tcpSynCl.Send(write_data, 0, write_data.Length, SocketFlags.None);
  int result = tcpSynCl.Receive(tcpSynClBuffer, 0, 
                 tcpSynClBuffer.Length, SocketFlags.None);
  
  byte function = tcpSynClBuffer[7];
  byte[] data;    
  
  if (result == 0) throw SystemException("No data received");
  
  // ... process log buffer ...
  
  _log.Debug(string.Format("[{0}]: Got sync response ({1}).", 
      this._IP.ToString(), CoreUtils.PayloadToString(data)));
  
  return data;
  </code></pre>
  
  <p>There were no exceptions thrown, which would suggest that something happened between Send() and Receive() under the hood. The time between the two debug log entries was twice as long than all the others. Possible or not possible?</p>