title: why a client side of tcp connection abruptly sends 5 TCP RST packets at once?
body: <p>the setup is the following:</p>
  
  <ul>
  <li>192.168.74.254 is a win 2008 server</li>
  <li>192.168.74.81 is an android client device (Lenovo N300 AiO)</li>
  </ul>
  
  <p>both interconnected by a HP V1910 switch and nothing more.  </p>
  
  <p>The client device connects to the server, reads some data and stays connected to it, waiting for more data that may come later. Every 1 sec the server sends a 'heartbeat' packet. The client device can passively receive data without sending anything for some time (this depends on the user behaviour), but sometimes it suddenly sends 5 RST packets at once. For the software running on it it looks as 'connection reset by peer' i.e. as if the server has closed the connection (although it was the device who sent 5 x RST). This can happen like 5 to 10 minutes after establishing the connection. Looking at a continuous ping command in the process we can see there are like 2 or 4 ping losses at this moment, or a couple of pings have unusually big delay (like up to 3000 ms instead of &lt;1ms).<br>
  This moment is shown in the wireshark log nr1 (<a href="http://i.stack.imgur.com/0s6j5.jpg" rel="nofollow">wireshark log 1 &amp; 2</a>).<br>
  In this case the client reopens the connection 10 seconds later.</p>
  
  <p>Sometimes this does not lead to connection reset. The client still sends 5 RST packets at once, but somehow the connection survives. This is shown in the wireshark log nr2 (see the same link above).</p>
  
  <p>Sometimes its not five RST packets in a row, but 5 duplicate ACKs in a row (see wireshark log nr3). But happening within the same slot of 400 - 480 seconds of client inactivity (not sending anything, just receiving, the server still sending 'heartbeats' every second). Sometimes this leads to connection reset, sometimes not. This is shown in the wireshark log nr3 (<a href="http://i.stack.imgur.com/NO98o.png" rel="nofollow">wireshark log 3</a>).</p>
  
  <p>All of the above happen in the same circumstances - the client passively reading data for 6 - 8 minutes, and nothing more.</p>
  
  <p>Can anyone explain this behaviour ? As it seems pretty strange to me. What can be the reason for the client to send those RSTs ? Why sometimes the connection survives not regarding those RSTs ? Why sometimes it is duplicate ACKs, not RSTs ?</p>
  
  <p>Thanks in advance for any insight.</p>
  
  <p>The stack trace on the android side, when this happens:</p>
  
  <pre><code>W/System.err(  669): java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)
  W/System.err(  669):    at libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:552)
  W/System.err(  669):    at libcore.io.IoBridge.recvfrom(IoBridge.java:516)
  W/System.err(  669):    at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
  W/System.err(  669):    at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
  W/System.err(  669):    at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
  W/System.err(  669):    at libcore.io.Streams.readSingleByte(Streams.java:41)
  W/System.err(  669):    at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:236)
  W/System.err(  669):    at xx.xxx.xxxxx.xxxxx.CServerConnection$2.run(CServerConnection.java:122)
  W/System.err(  669):    at java.lang.Thread.run(Thread.java:856)
  W/System.err(  669): Caused by: libcore.io.ErrnoException: recvfrom failed: ECONNRESET (Connection reset by peer)
  W/System.err(  669):    at libcore.io.Posix.recvfromBytes(Native Method)
  W/System.err(  669):    at libcore.io.Posix.recvfrom(Posix.java:136)
  W/System.err(  669):    at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164)
  W/System.err(  669):    at libcore.io.IoBridge.recvfrom(IoBridge.java:513)
  W/System.err(  669):    ... 7 more
  </code></pre>
  
  <p>The java client code running on the android device:</p>
  
  <pre><code>private InputStream is;
  
  private Runnable runnable = new Runnable() {
      byte[] readBuffer = new byte[65536*2];
  
      @Override
      public void run() {
  
          while (!stop) {
              try {
                  int read = is.read();
  
                  if (read == -1)
                      break;
  
                  else {
                       //process data
                  }
              } catch (Exception e) {
                  e.printStackTrace();
                  break;
              }
          }
  
          reconnect();
      }
  };
  
  private void reconnect() {
      if (stop) {
          return;
      }
  
      try {
          disconnect(); }
      catch (Exception e) {
          e.printStackTrace();
      }
  
      receiveMessageCallback.disconnected();
  
      new Thread(new Runnable() {
          @Override
          public void run() {
              while (true) {
                  try {
                      Thread.sleep(reconnectTimeout);
                      connect(host, port);
                      break;
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              }
          }
      }).start();
  }
  </code></pre>