如何找到哪个进程绑定套接字但不监听?

Xii*_*Liu 6 sockets linux bind

当我使用nc来监听端口时,它会显示出来

nc -l -vv -p 21000

retrying local 0.0.0.0:21000 : Address already in use Can't grab 0.0.0.0:21000 with bind
Run Code Online (Sandbox Code Playgroud)

但是我无法使用工具netstat/ss找到哪个任务占用了这个端口

netstat -an|grep 21000 
Run Code Online (Sandbox Code Playgroud)

没有找到

ss -a|grep 21000 
Run Code Online (Sandbox Code Playgroud)

没有找到

这个端口被我的java程序占用,代码是:

public class Test1 {

        public static void main(String[] args) throws InterruptedException {
        Socket s = new Socket();
        try {
            s.bind(new InetSocketAddress("127.0.0.1",21000));
        } catch (IOException e) {
            e.printStackTrace();

        }
        Thread.sleep(500000000000L);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我绑定一个套接字,但不要与连接或监听一起使用它.我进入/ proc/[java task id]/fd,发现这个套接字的inode是"socket:[3073501]"但我找不到inode或端口,即使在/ proc/net/tcp或/ proc中也是如此/ NET/TCP6

是否有任何方法可以找到绑定套接字但不监听或连接的进程.

谢谢.

我看到linux 3.10.0-327源代码.我认为文件/ proc/net/tcp的内容来自net/ipv4/tcp_ipv4.c.

在tcp_proc_register方法中,

static void *tcp_get_idx(struct seq_file *seq, loff_t pos)      
{
        void *rc;
        struct tcp_iter_state *st = seq->private;

        st->state = TCP_SEQ_STATE_LISTENING;
        rc        = listening_get_idx(seq, &pos);

        if (!rc) {
                st->state = TCP_SEQ_STATE_ESTABLISHED;
                rc        = established_get_idx(seq, pos);
        }

        return rc;
}
Run Code Online (Sandbox Code Playgroud)

它仅显示侦听中的socks或从tcp_hashinfo建立的socks.但是tcp_hashinfo有三个结构

struct inet_bind_hashbucket     *bhash; 
struct inet_listen_hashbucket   listening_hash[INET_LHTABLE_SIZE];
struct inet_ehash_bucket        *ehash;
Run Code Online (Sandbox Code Playgroud)

bhash可用于绑定.但是不会在/ proc/net/tcp中导出.

Ste*_*cht 2

我在Ubuntu下测试了你的Java程序。

如何找到绑定了套接字但不监听或连接的进程:

拉索夫

lsof | grep "can't identify protocol"
Run Code Online (Sandbox Code Playgroud)

您将得到如下结果:

COMMAND     PID   TID       USER   FD      TYPE             DEVICE SIZE/OFF    NODE NAME
java      29644 29653    stephan   12u     sock                0,7      0t0  312066 can't identify protocol
Run Code Online (Sandbox Code Playgroud)

请注意 TYPEsock和 NAME can't identify protocol

这是如何运作的?查看 lsof 的常见问题解答:

为什么基于 /proc 的 lsof 报告某些套接字文件“无法识别协议”?

基于 /proc 的 lsof 可能会报告:

  COMMAND PID ... TYPE ... NODE NAME
  pump    226 ... sock ...  309 can't identify protocol
Run Code Online (Sandbox Code Playgroud)

这意味着它无法识别打开的套接字文件所使用的协议(即 AF_* 名称)。Lsof 通过将 /proc//fd 条目关联的节点号与 /proc/net 子目录的选定文件中找到的节点号相匹配来识别协议。

...

您可能无法找到所需的节点号,因为并非所有内核协议模块都完全支持 /proc/net 信息。

验证流程

lsof 输出中的 PID 为 29644。

ls -l /proc/29644/fd   
Run Code Online (Sandbox Code Playgroud)

结果是:

...
lrwx------ 1 stephan stephan 64 Jul  7 22:52 11 -> socket:[312064]
lrwx------ 1 stephan stephan 64 Jul  7 22:52 12 -> socket:[312066]
...
Run Code Online (Sandbox Code Playgroud)

grep 312066 /proc/net/*
Run Code Online (Sandbox Code Playgroud)

给出一个空结果。