是否可以在客户端和服务器端关闭Java套接字?

时间:2010-01-29 22:33:24

标签: java sockets tcp

我在两个java应用程序之间有一个套接字tcp连接。当一侧关闭插座时,另一侧保持打开状态。但是我希望它能够关闭。而且我也迫不及待地想看看它是否可用,然后关闭它。我想从某一方面完全关闭它。 我该怎么办?

5 个答案:

答案 0 :(得分:10)

TCP不能像这样工作。操作系统不会释放资源,即文件描述符,从而释放端口,直到应用程序显式关闭套接字或死亡,即使TCP堆栈知道另一方关闭它。在从对等方接收FIN时,没有从内核到用户应用程序的回调。操作系统向另一方确认,但等待应用程序在发送其FIN数据包之前调用close()。看看TCP state transition diagram - 您在被动关闭框中。

在没有为每个套接字专用线程的情况下检测这种情况的一种方法是使用select/poll/epoll/kqueue系列函数。被动关闭的套接字将作为可读信号发出信号,并且读取尝试将返回EOF。

希望这有帮助。

答案 1 :(得分:6)

双方都必须从连接中读取,以便他们可以检测到对等方何时关闭。当读取返回-1时,这意味着另一端关闭连接,这是你结束关闭的线索。

答案 2 :(得分:4)

如果您仍在从插座中读取数据,那么当它关闭时您将检测到-1。

如果您不再从插座中读取数据,请继续关闭它。

如果它们都不是,那么你可能正在等待事件。这不是您想要处理数千个端口的方式! Java将开始在Windows中大约3000个线程中获取 - 在Linux中更少(我不知道为什么)。

确保您使用的是NIO。使用单个线程来管理所有端口(连接池)。它应该只是从线程中获取数据,将其转发到队列中。那时我想我有一个线程池从队列中取出数据并处理它,因为从端口实际处理数据需要一些时间。

将线程附加到每个端口将不起作用,这是NIO需要的最大原因。

此外,在您的流中使用某种“关闭”消息来触发关闭端口可能会使事情更快 - 但您仍然需要处理-1来覆盖损坏的流的情况< / p>

答案 3 :(得分:3)

通常的解决方案是让对方知道你要在实际关闭之前关闭连接。例如,对于SMTP协议,服务器将在关闭连接之前发送“221 Bye”。

答案 4 :(得分:-1)

您可能想要一个连接池。