java - Apache Mina,如何检测何时使用无效套接字向客户端发送消息?

标签 java sockets tcp mina

我有一个使用 MINA 版本 2 的服务器设置。 我对套接字和 tcp 没有太多经验。

问题是如果我连接到我的服务器,然后拔下我的互联网并关闭连接,(服务器没有收到连接关闭的通知)服务器将永远认为我的连接仍然有效并且有效。

服务器将继续向我的连接发送消息,并且不会抛出任何异常,即使我的计算机上没有任何内容绑定(bind)到本地端口也是如此。

如何测试连接是否仍然存在?

我试过在 Debug模式下运行 MINA 日志,并记录

 IoSession.isConnected() IoSession.isActive IoSession.isClosing

他们总是返回真、真、假。此外,在 Debug模式下,没有有用的信息表明连接已丢失。它只是记录了常规的“已发送消息”内容,就好像没有任何问题一样。

在使用 Flash actionscript 时,我有过 flash 在无效套接字上运行时会抛出错误的经历。这让我相信这是在说服务器上的套接字不再对连接有效。所以换句话说,如果闪存可以检测到无效的套接字,那么 Java 服务器也应该能够正确地检测到它?

如果真的没有办法检测死连接,我总是可以设置一个连接保持 Activity 例程,客户端不断向服务器发送“我在这里”消息,并且服务器关闭没有连接的 session 传入消息几秒钟。


编辑:在了解到“套接字”是私有(private)的并且从不在网络上共享之后,我设法为我的问题找到了更好的结果,并且我找到了这个 SO 线程。

Java socket API: How to tell if a connection has been closed?

不幸的是

IOException 'Connection reset by peer' Doesn't occur when I write to the IoSession in MINA.


编辑:

在 Java 中是否有任何方法可以检测在发送数据包后何时未收到对 TCP 数据包的 ACK? ACK 超时?


编辑:

但显然,我的计算机应该向服务器发送 RST?根据这个答案。 https://stackoverflow.com/a/1434592/4425643 但这似乎是一种糟糕的端口扫描方式。这是端口扫描的工作原理吗?端口扫描器将数据发送到端口,受害者的服务以 RST 响应?抱歉,我想我需要一个新问题来解决所有这些问题。但奇怪的是,MINA 在发送数据时并没有抛出 connection reset by peer。那么我的计算机不会发送 RST。

最佳答案

Internet 协议(protocol)中的套接字连接 的概念是一种错觉。这是操作系统和 TCP 堆栈为您提供的一种方便的抽象,但实际上,这都是假的。

在幕后,Internet 上的所有内容都采用单个数据包的形式。

从一台计算机向另一台计算机发送数据包的角度来看,没有内置的方法可以知道该计算机是否真的在接收数据包,除非该计算机(或介于两者之间的其他计算机,如路由器)告诉您数据包是否已收到。

从一台期望从另一台计算机接收数据包的计算机的角度来看,没有办法提前知道是否有任何数据包即将到来,永远会到来,或者以什么顺序到来——直到它们实际到达。一旦它们到达,您收到一个包裹这一事实并不意味着您将来会收到更多。

这就是为什么我说连接或套接字是一种幻觉。操作系统确定连接是否“Activity ”的方式很简单,就是等待任意时间。在这段时间之后——称为超时——如果 TCP 连接的一侧没有收到另一侧的回音,它将假定另一端已断开连接,并且任意将连接状态设置为“关闭”、“死”或“终止”(“超时”)。

所以:

  • 您的服务器不知道您已经断开了 Internet 连接。它无法知道这一点。
  • 您的服务器的 TCP 堆栈已配置成某种方式,如果未收到响应,则在另一端“放弃”之前等待任意时间。如果此超时设置为非常长的时间段,您可能会觉得您的服务器卡在不再有效的连接上。如果这让您感到困扰,您应该研究减少超时间隔的方法。

打个比方:如果您正在与某人通电话,而他们很可能会受伤或丧生,而您正在与他们通话并让他们接听电话,然后电话突然没电了... .. 那么,你要等多久?你认为对方在什么时候受伤或死亡?如果您等待几毫秒,在大多数情况下,这对“超时”来说太了,因为其他人可能只是在倾听并思考如何回应。如果再等50年,那人可能早就死了。因此,您必须设置一个有意义的合理超时值。

关于java - Apache Mina,如何检测何时使用无效套接字向客户端发送消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39517015/

相关文章:

c - 对于大多数数据包,我的 TCP 校验和函数返回 0

python - 来自 RAW SOCKET 数据包嗅探的 TCP 连接状态

java - 在重写的 JTable 中的构造函数之前调用的方法

c# - BeginSend<IList<ArraySegment....) 是否执行所有 ArraySegment 的原子发送?

c# - C#中具有多个网络的UDP组播

linux - ICMP 套接字 (Linux)

networking - TCP 是否有可能通过多个连接实现更高的传输速率?

java - Null/Object和Null/Null比较效率

java - 进度条每 100 秒递增 1

java - 如何访问存储为 MIME 部件的附件?