设置如下:
两者都通过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();
}