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

时间:2022-08-26 19:54:09

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应用程序之间有一个套接字tcp连接。当一侧关闭插座时,另一侧保持打开状态。但我希望它能够关闭。我也迫不及待地想看看它是否可用,然后关闭它。我想从某一方面完全关闭它。我能做什么?

5 个解决方案

#1


10  

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 close box.

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

One way to detect a situation like this without dedicating a thread to each socket is to use the select/poll/epoll/kqueue family 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.

希望这可以帮助。

#2


6  

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.

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

#3


4  

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以覆盖损坏的流的情况

#4


3  

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”。

#5


-1  

You probably want to have a connection pool.

您可能想要一个连接池。

#1


10  

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 close box.

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

One way to detect a situation like this without dedicating a thread to each socket is to use the select/poll/epoll/kqueue family 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.

希望这可以帮助。

#2


6  

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.

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

#3


4  

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以覆盖损坏的流的情况

#4


3  

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”。

#5


-1  

You probably want to have a connection pool.

您可能想要一个连接池。