![如何使端口专用于特定的预定进程?](https://linux22.com/image/97058/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%AB%AF%E5%8F%A3%E4%B8%93%E7%94%A8%E4%BA%8E%E7%89%B9%E5%AE%9A%E7%9A%84%E9%A2%84%E5%AE%9A%E8%BF%9B%E7%A8%8B%EF%BC%9F.png)
我们有一个 XYZ 批处理流程,每天凌晨 2:00 启动。此 XYZ 配置为在端口 59070 上启动。完成后,此端口将成为开放端口。但最近我们遇到了一个问题,另一个进程正在使用 59070,当这个 XYZ 进程启动时,它无法运行。
作为解决方法,我们已将配置更新到不同的端口 59071 并正常运行该过程。我的疑问是,我们是否可以阻止此端口 59070 并确保没有其他进程使用它?我们使用的是 Solaris 10。
答案1
端口 59070 是临时端口- 一个可以用于出境任何进程的 TCP 连接。 (端口 59071 也是如此,所以这并不是一个很好的解决方法......)
在 Solaris 上,临时端口范围由以下方式设置的tcp_smallest_anon_port
和tcp_largest_anon_port
可调参数。默认范围是 32,768 到 65,535。该范围内的任何端口都可能正在使用中随时通过传出 TCP 连接。
正如 @Jeff Schaller 的回答所述,端口是按照先到先得的原则使用的,因此“保留”端口的唯一方法是始终将某些东西绑定到它。请注意,在该答案中,另一个进程可能会在杀死“端口保护程序”脚本和实际使用该端口的“正常”进程之间的时间内获取有问题的端口bind()
。它不是可能,诚然,但这可能会发生。如果您的处理至关重要,我认为您需要担心这一点。
我建议不要使用临时端口和/或将你的进程配置为一直运行,或者用于inetadm
配置自动运行您的进程的服务。这将导致inetd
进程始终绑定到“您的”端口,从而有效地保留它供您使用。
答案2
除了自己主动使用端口之外,我不知道有什么方法可以阻止端口的使用。我提出的总体想法是将批处理更改为:
杀死“端口保护程序”脚本
运行正常的批处理
启动一个新的“端口保护程序”脚本
此解决方法将帮助防止恶意进程绑定到您想要的端口(进程可能会在步骤 1 和 2 之间或步骤 2 和 3 之间抢占端口),但它会不是防止批处理过程出现意外,即批处理过程似乎已结束但未释放端口(通过退出其所有进程)。
Perl 中的示例“端口保护程序”脚本如下:
#!/usr/bin/env perl
# listens on the given port
use strict;
use IO::Socket;
my $port = shift or die "Usage: $0 <port>";
my $socket = new IO::Socket::INET(
LocalHost => '0.0.0.0',
LocalPort => $port,
Proto => 'tcp',
Listen => 1,
Reuse => 1,
)
or die "Cannot create socket: $!\n";
while (1) {
my $c = $socket->accept();
shutdown($c, 2);
}
您需要保存脚本的 PID 或找到并终止它,因为它在保持给定端口打开的同时运行无限循环。