如何在 AIX 7.1 中获取真实侦听器 PID?不应该rmsock
像互联网上广泛描述的那样工作吗?
https://www-01.ibm.com/support/docview.wss?uid=isg3T1019570
案子:
有一个程序同时实现服务器和客户端协议,该协议在运行时由参数选择。就像:
$ myprogram -switcher-mode:port
$ myprogram -provider-mode:port
一旦监听器启动,我们就可以使用 获取它的 PID rmsock
。我们假设任意端口号 40000:
$ netstat -Aan | grep '\.40000.*LISTEN$' | awk '{ print $1 }' | xargs -n1 -i rmsock {} tcpcb
The socket 0xf1000e000334b808 is being held by proccess 10683226 (serviceprg)
$ ps -fp 10683226
UID PID PPID C STIME TTY TIME CMD
test 10683226 1 0 08:17:43 - 2 serviceprg -switcher-mode:40000
我们可以看到这是正确的进程,即监听端口的切换器:serviceprg-切换器模式:40000。
当问题开始时:
一旦我们在提供者模式下启动新进程(在后台),它们rmsock
可能会返回它们的 PID,就好像它们是侦听器一样(它是随机的)。然而,当切换器“感觉”需要更多提供者来执行突发请求时,这些进程可能会通过手动和自动两种方式启动(这两种方式都会导致问题),因此它使用这样的libc.a
功能启动更多提供者system()
:
system("serviceprg -provider-mode:40000 1>/dev/null 2>/dev/null &");
因此,当我们使用它检查列表器 PID 时,它rmsock
可能会返回错误的 PID,如下所示:
$ netstat -Aan | grep '\.40000.*LISTEN$' | awk '{ print $1 }' | xargs -n1 -i rmsock {} tcpcb
The socket 0xf1000e000334b808 is being held by proccess 10690461 (serviceprg)
$ ps -fp 10690461
UID PID PPID C STIME TTY TIME CMD
test 10690461 1 0 08:20:04 - 1:10 serviceprg -provider-mode:40000
检查为该 PID 运行的程序是否是在真正的侦听器之后启动的进程,并且它不侦听该端口,而是作为客户端程序连接到该端口:serviceprg-提供者模式:40000
当我们杀死该进程时,假设上面的 PID 10690461rmsock
会发生变化,并可能错误地应答另一个进程作为侦听器(或者是真实的进程,这种行为似乎是随机的),当您杀死连接到该端口的每个客户端时,那么rmsock
将始终返回真实监听器的正确PID。
如果您想更多地了解其架构:其他程序连接到该端口请求服务,侦听器是一个切换器,它将每个客户端请求传递到提供服务的程序的实例,但在这种情况下,它是同一个程序并且连接到相同的端口,请查看如下图:
答案1
由于netstat -Aan
没有提供完整的进程列表,为了区分提供者进程和切换器进程,您必须收集 PCB ID,然后收集 PID,然后检查参数:
for pid in $(netstat -Aan | grep '\.40000.*LISTEN$' | awk '{ print $1 }' | xargs -n1 -i rmsock {} tcpcb | awk '{print $9}')
do
ps -o args= -p "$pid" | grep -q "provider-mode:" && echo this is a provider
ps -o args= -p "$pid" | grep -q "switcher-mode:" && echo this is a switcher
done