Linux:如何终止使用1935端口的程序?

10

我在我的Linux服务器上运行一个JAVA的red5服务器

有时候,服务器会关闭。当我尝试重新启动它时,会出现一个错误:

"绑定错误,该端口已被占用"。

所以我尝试使用killall -9 java命令杀掉服务器进程,并尝试重启服务器:但是还是会遇到相同的错误。

我必须等待一段时间(大约2-3分钟)然后再次重启服务器:这样就可以正常工作了。

我想知道为什么当我杀死进程后,我仍然需要等待2-3分钟才能释放1935端口并再次运行服务器。

是否有一种方法可以立即杀死进程并释放端口?


1
我不相信那些将SIGKILL归咎于端口清理失败的答案。操作系统完全知道进程已经结束,并以标准方式释放其资源。刚关闭的TCP监听端口的标准方式是在一段时间内不可用,以防止连接到错误的服务器。可以通过使用Justin答案中提到的SO_REUSEADDR最轻松地避免这种情况。 - Peter G.
6个回答

18
如果您确定旧的服务器实例仍在占用该端口,只需运行jps,找到列表中的服务器pid并运行kill -9 my_pid 对于一般非Java进程,lsof -i :1935通常适用于我。再次获取pid并杀死该进程。

10
问题在于kill命令中的"-9"参数。如果使用SIGKILL (-9)信号杀死进程,该进程会立即终止。因此端口会一直被占用,直到操作系统(几分钟后)发现这个问题。建议先尝试使用SIGHUP和SIGINT信号(按顺序),再使用SIGKILL。无论如何,请使用"netstat -a -t -p"命令验证哪个进程已经占用了该端口。

9

立即处理终止和端口释放:

 fuser -k 1935/tcp

5
如果可能的话,当您的程序设置其套接字时,应使用套接字SO_REUSEADDR选项。这样一来,当程序重新启动时,您可以立即重用套接字,而不必等待2-3分钟。
有关更多信息,请参见javadoc setReuseAddress。特别是:
当TCP连接关闭时,连接可能会在关闭连接后保持超时状态一段时间(通常称为TIME_WAIT状态或2MSL等待状态)。对于使用已知套接字地址或端口的应用程序,如果存在涉及套接字地址或端口的超时状态连接,则可能无法将套接字绑定到所需的SocketAddress。
在使用bind(SocketAddress)绑定套接字之前启用SO_REUSEADDR允许绑定套接字,即使先前的连接处于超时状态。

他可以在Java中通过调用setReuseAddress来实现这一点。http://download.oracle.com/javase/1.4.2/docs/api/java/net/ServerSocket.html - Peter G.
看起来我们都在想同样的事情 - 看看我的编辑 :) - Justin Ethier

2
这是一个方便的一行代码:
kill $(fuser 1935/tcp)

1

默认情况下不应使用kill -9。该进程无法清理内部内容。 例如,要杀死使用端口8000的应用程序的pid:

kill $(netstat -nptl | awk '/:8000/{gsub("/.*", ""); print $7}')

kill命令:用法:kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... 或 kill -l [sigspec] - yarek
似乎这个命令有错误:kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]。 - yarek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接