是否可以在客户端和服务器端关闭 Java 套接字?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2165670/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to close Java sockets on both client and server sides?
提问by Shayan
I have a socket tcp connection between two java applications. When one side closes the socket the other side remains open. but I want it to be closed. And also I can't wait on it to see whether it is available or not and after that close it. I want some way to close it completely from one side. What can I do?
我在两个 java 应用程序之间有一个 socket tcp 连接。当一侧关闭插座时,另一侧保持打开状态。但我希望它被关闭。而且我迫不及待地想看看它是否可用,然后关闭它。我想要某种方式从一侧完全关闭它。我能做什么?
回答by Nikolai Fetissov
TCP doesn't work like this. The OS won't release the resources, namely the file descriptor and thus the port, until the application explicitly closes the socket or dies, even if the TCP stack knows that the other side closed it. There's no callback from kernel to user application on receipt of the FIN from the peer. The OS acknowledges it to the other side but waits for the application to call close()before sending its FIN packet. Take a look at the TCP state transition diagram- you are in the passive closebox.
TCP 不是这样工作的。操作系统不会释放资源,即文件描述符和端口,直到应用程序明确关闭套接字或死亡,即使 TCP 堆栈知道另一端关闭了它。收到来自对等方的 FIN 后,内核不会回调到用户应用程序。操作系统向另一方确认它,但close()在发送其 FIN 数据包之前等待应用程序调用。看一下TCP 状态转换图- 您在被动关闭框中。
One way to detect a situation like this without dedicating a thread to each socket is to use the select/poll/epoll/kqueuefamily of functions. The socket being passively closed will be signaled as readable and read attempt will return the EOF.
在不为每个套接字指定线程的情况下检测这种情况的一种方法是使用select/poll/epoll/kqueue函数系列。被动关闭的套接字将被标记为可读,读取尝试将返回 EOF。
Hope this helps.
希望这可以帮助。
回答by nos
Both sides have to read from the connection, so they can detect when the peer has closed. When read returns -1 it will mean the other end closed the connection and that's your clue to close your end.
双方都必须从连接中读取数据,以便他们可以检测到对等方何时关闭。当 read 返回 -1 时,这意味着另一端关闭了连接,这就是你关闭一端的线索。
回答by Bill K
If you are still reading from your socket, then you will detect the -1 when it closes.
如果您仍在从套接字读取,那么您将在关闭时检测到 -1。
If you are no longer reading from your socket, go ahead and close it.
如果您不再从套接字读取,请继续关闭它。
If it's neither of these, you are probably having a thread wait on an event. This is NOT the way you want to handle thousands of ports! Java will start to get pukey at around 3000 threads in windows--much less in Linux (I don't know why).
如果两者都不是,则您可能有一个线程在等待事件。这不是您想要处理数千个端口的方式!Java 将在 Windows 中的大约 3000 个线程处开始变得流行——在 Linux 中更少(我不知道为什么)。
Make sure you are using NIO. Use a single thread to manage all your ports (connection pool). It should just grab the data from a thread, forward it to a queue. At that point I think I'd have a thread pool take the data out of the queues and process it because actually processing the data from a port will take some time.
确保您使用的是 NIO。使用单个线程来管理所有端口(连接池)。它应该只是从线程中获取数据,然后将其转发到队列中。那时我想我会有一个线程池从队列中取出数据并处理它,因为实际处理来自端口的数据需要一些时间。
Attaching a thread to each port will NOT work, and is the biggest reason NIO was needed.
将线程附加到每个端口是行不通的,这是需要 NIO 的最大原因。
Also, having some kind of a "Close" message as part of your stream to trigger closing the port may make things work faster--but you'll still need to handle the -1 to cover the case of broken streams
此外,将某种“关闭”消息作为流的一部分来触发关闭端口可能会使事情更快地运行 - 但您仍然需要处理 -1 以涵盖损坏的流的情况
回答by Confusion
The usual solution is to let the other side know you are going to close the connection, before actually closing it. For instance, in the case of the SMTP protocol, the server will send '221 Bye' before it closes the connection.
通常的解决方案是在实际关闭连接之前让对方知道您将关闭连接。例如,在 SMTP 协议的情况下,服务器将在关闭连接之前发送“221 Bye”。
回答by Roman
You probably want to have a connection pool.
您可能想要一个连接池。

