Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ApacheMina,如何检测您';是否使用无效套接字向客户端重新发送消息?_Java_Sockets_Tcp_Mina - Fatal编程技术网

Java ApacheMina,如何检测您';是否使用无效套接字向客户端重新发送消息?

Java ApacheMina,如何检测您';是否使用无效套接字向客户端重新发送消息?,java,sockets,tcp,mina,Java,Sockets,Tcp,Mina,我有一个使用MINA版本2的服务器设置。 我对套接字和tcp没有太多经验 问题是,如果我连接到我的服务器,然后拔下internet并关闭连接,(服务器没有收到连接关闭的通知),服务器将永远认为我的连接仍然处于活动状态且有效 服务器将继续向我的连接发送消息,并且不会抛出任何异常,即使我的计算机上没有绑定到本地端口的任何内容 如何测试连接是否仍然存在 我已经尝试在调试模式下运行MINA日志记录,并记录 IoSession.isConnected() IoSession.isActive IoSes

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

问题是,如果我连接到我的服务器,然后拔下internet并关闭连接,(服务器没有收到连接关闭的通知),服务器将永远认为我的连接仍然处于活动状态且有效

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

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

我已经尝试在调试模式下运行MINA日志记录,并记录

 IoSession.isConnected() IoSession.isActive IoSession.isClosing
它们总是返回真、真、假。此外,在调试模式下,没有有用的信息表明连接丢失。它只是记录了常规的“发送消息”内容,好像没有什么问题

通过使用FlashActionScript,我有过这样的经历:Flash会抛出错误,即它在一个无效的套接字上运行。这让我相信,这意味着服务器上的套接字对于连接不再有效。换句话说,如果flash能够检测到无效的套接字,那么Java服务器应该能够检测到它是否正确

如果真的没有办法检测到死连接,我可以设置一个连接保持活动例程,客户端不断向服务器发送“我在这里”消息,服务器关闭几秒钟内没有传入消息的会话


编辑:在了解到“套接字”是私有的,从来没有在网络上共享过之后,我设法为我的问题找到了更好的结果,我发现这个线程非常有用。

不幸的是

IOException“由对等方重置连接”在写入时不会发生 米纳的失踪


编辑: 在Java中,是否有任何方法可以检测发送数据包后是否没有收到TCP数据包的ACK?确认超时


编辑: 然而很明显,我的计算机应该向服务器发送RST吗?根据这个答案。 但这似乎是一种糟糕的端口扫描方式。端口扫描就是这样工作的吗?端口扫描器将数据发送到一个端口,受害者的服务用RST响应?对不起,我想我需要一个新问题来回答这一切。但奇怪的是,MINA在发送数据时并没有抛出对等方重置的连接。因此,我的计算机不会发送RST。

互联网协议中的套接字或连接概念是一种幻觉。它是操作系统和TCP堆栈提供给您的一种方便的抽象,但实际上,它都是假的

在这种情况下,互联网上的一切都是以单个数据包的形式出现的

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

从一台计算机期望从另一台计算机接收数据包的角度来看,在数据包实际到达之前,无法预先知道数据包是否正在到达、是否会到达或以什么顺序到达。一旦他们到达,你收到一个包裹并不意味着你将来会收到更多

这就是为什么我说连接或插座是一种错觉。操作系统确定连接是否处于“活动”状态的方法只是等待任意时间。在这段时间(称为超时)之后,如果TCP连接的一端没有收到另一端的回音,它将假定另一端已断开连接,并任意将连接状态设置为“关闭”、“死”或“终止”(“超时”)

因此:

  • 您的服务器不知道您已拔出Internet连接的插头。它无法知道这一点
  • 您的服务器的TCP堆栈已配置为在未收到响应的情况下,在另一端“放弃”之前等待任意时间。如果将此超时设置为非常长的时间段,您可能会觉得服务器正在挂起不再有效的连接。如果这让您感到困扰,您应该寻找减少超时间隔的方法

打个比方:如果你在和某人打电话,而他们真的有受伤或死亡的危险,你正在和他们交谈,让他们接电话,然后电话突然断了。。。。。那么,你要等多久?你认为对方在什么时候受伤或死亡?如果你等几毫秒,在大多数情况下,这是太短的“超时”,因为其他人可能只是在听和思考如何回应。如果你等50年,这个人可能早就死了。因此,您必须设置一个合理的、有意义的超时值。

您需要的是一个KeepAlive、heartbeat或ping

根据@allquicatic的回答,在TCP中没有完全可靠的内置方法来实现这一点。您必须实现一种方法来明确地询问客户机“您还在吗?”并等待一段指定时间的回答

keepalive(KA)是一个设备向另一个设备发送的消息,用于检查两个设备之间的链路是否正在运行,或防止此链路中断

在计算机科学中,心跳信号是由硬件或软件生成的周期性信号,用于指示系统的正常运行或同步系统的其他部分。[1]通常心跳信号在机器之间以秒为单位的固定间隔发送。如果有一段时间没有接收到心跳信号,通常每隔几次心跳信号,则认为本应发送心跳信号的机器出现故障。[2]

最简单的实现方法是定期发送