如果我的套接字已连接且未关闭,为什么要发送RST?

时间:2017-06-21 20:07:17

标签: android sockets tcp

我有一个使用java.net.Socket与PC无线通信的Android设备。一切都很好,但如果我没有做任何事情(即没有网络使用)正好1分钟,那么当Android向PC发送数据包时,PC会收到它并发送一个ACK,但Android会以RST响应。

来自Wireshark(10.1.2.1是Android,10.1.2.11是PC)......

  

356 0.112470 10.1.2.1 10.1.2.11 TCP 97 34360→181 [PSH,ACK] Seq = 1   Ack = 1 Win = 4935 Len = 31 TSval = 156103571 TSecr = 320673352

     

359 0.000011 10.1.2.11 10.1.2.1 TCP 66 181→34360 [ACK] Seq = 1 Ack = 32   Win = 260 Len = 0 TSval = 320738236 TSecr = 156103571

     

360 0.000304 10.1.2.1 10.1.2.11 TCP 60 34360→181 [RST] Seq = 32 Win = 0   LEN = 0

此时,如果我询问套接字的成员变量,它说。 。 。

  • isConnected = true
  • isCreated = true
  • isInputShutdown = false
  • isOutputShutdown = false
  • isClosed = false
  • isBound = true

...看起来我应该仍然接收数据包就好了。 那我怎么弄清楚为什么我发送RST

N.B。 - 没有设置“休眠”或关闭此设备上启用的wifi或显示器或任何其他节电功能设置。

4 个答案:

答案 0 :(得分:2)

1分钟的延迟看起来像是超时。它可能是SO_TIMEOUT,但这不会自己生成网络活动。此外,发送的最后一个数据包包含31个字节的数据似乎表明涉及该应用程序。可能的情况是:

  • Android应用程序超时(单独或由套接字SO_TIMEOUT触发)
  • 它发送最后一块数据,例如通过刷新输出流。
  • 它突然关闭套接字,例如使用setSoLinger(true, 0)套接字选项。

答案 1 :(得分:1)

这些Socket方法都没有返回连接状态。它们都与java.net.Socket 对象的内部状态有关,这取决于您在其上调用的构造函数和方法。如果对等方断开连接,他们就不会神奇地开始返回false

当你去使用套接字获取I / O时,你会发现你将获得IOException: 'connection reset'

为什么重置连接是另一回事。通常的原因是您已经发送到已经被对等方关闭的连接,或者对等方关闭了连接而没有读取已经到达的所有数据。换句话说,应用程序协议错误。还有其他原因,但这些是最常见的原因。

答案 2 :(得分:1)

这可能是由于NAT路由器在超时后尝试关闭套接字以释放资源。启用keep_alive可能会有所帮助。您还可以尝试使用静态IP地址创建自己的网络,绕过路由器以排除此假设。

答案 3 :(得分:0)

当连接关闭时,isClosed()方法应返回TRUE。 即使连接已关闭,isConnected()方法也可以返回TRUE,因为该方法告诉您“如果您设法连接”,则断开连接时变量状态不会更改/刷新。

但是在您的情况下,根据文档,连接肯定没有关闭。 有关详细信息,请参阅:

https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html#isConnected--

https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html#isClosed--

注意:可能会帮助您设置为 TRUE setKeepAlive(boolean)

另见:

https://docs.oracle.com/javase/8/docs/api/java/net/SocketOptions.html#SO_KEEPALIVE

https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html#setKeepAlive-boolean-

回到问题,请检查以下其中一项:

  1. 您能否确定由于某种原因没有其他设备 与Android相同的IP?也关掉你3G / 4G并留下来 仅在无线网络中连接。
  2. 是否有路由器在做NAT?在这种情况下,路由器可以发送 重置标志。
  3. 如果一切似乎都很好(这是你的Android手机用RST回复)并且SO_KEEPALIVE不起作用那么可能是某些应用程序级错误导致连接中断。