为什么tcp连接的客户端突然一次发送5个TCP RST数据包?

时间:2016-03-21 21:42:51

标签: android linux sockets networking tcp

设置如下:

  • 192.168.74.254是win 2008服务器
  • 192.168.74.81是一个Android客户端设备(联想N300 AiO)

两者都通过HP V1910交换机互连,仅此而已。

客户端设备连接到服务器,读取一些数据并保持连接,等待稍后可能出现的更多数据。每1秒,服务器发送一个“心跳”数据包。客户端设备可以被动地接收数据而不会发送任何东西一段时间(这取决于用户行为),但有时它会突然一次发送5个RST数据包。对于在其上运行的软件,它看起来像是“通过对等方重置连接”,即好像服务器已关闭连接(尽管它是发送5 x RST的设备)。建立连接后5到10分钟就会发生这种情况。在此过程中查看连续的ping命令,我们可以看到此时有2或4个ping丢失,或者几个ping具有异常大的延迟(例如高达3000 ms而不是<1ms)。 此时刻显示在wireshark log nr1(wireshark log 1 & 2)中 在这种情况下,客户端会在10秒后重新打开连接。

有时这不会导致连接重置。客户端仍然一次发送5个RST数据包,但不知何故,连接仍然存在。这显示在wireshark log nr2中(参见上面的相同链接)。

有时连续不是5个RST数据包,而是连续5个重复的ACK(参见wireshark log nr3)。但是在400到480秒的客户端不活动的同一个插槽内发生(不发送任何东西,只是接收,服务器仍然每秒发送'心跳')。有时这会导致连接重置,有时不会。这显示在wireshark log nr3(wireshark log 3)中。

以上所有情况都发生在相同的情况下 - 客户被动地读取数据6到8分钟,仅此而已。

任何人都可以解释这种行为吗?因为这对我来说似乎很奇怪。客户发送这些RST的原因是什么?为什么有时连接存在而不是关于那些RST?为什么有时它是重复的ACK,而不是RST?

提前感谢任何见解。

当发生这种情况时,android端的堆栈跟踪:

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

在Android设备上运行的java客户端代码:

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();
}

0 个答案:

没有答案