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

时间:2018-06-14 03:20:51

标签: linux sockets 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

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

netstat -an|grep 21000 

;没有找到

ss -a|grep 21000 

;没有找到

这个端口被我的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);
    }
}

当我绑定套接字时,但不要将它与connect或listen一起使用。 我进入/ proc / [java task id] / fd,找到这个socket的inode是" socket:[3073501]" 但我甚至无法在/ proc / net / tcp或/ proc / net / tcp6

中找到inode或端口

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

感谢。

我看到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;
}

它仅显示侦听中的socks或从tcp_hashinfo建立的socks。但是tcp_hashinfo有三个struct

struct inet_bind_hashbucket     *bhash; 
struct inet_listen_hashbucket   listening_hash[INET_LHTABLE_SIZE];
struct inet_ehash_bucket        *ehash;

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

1 个答案:

答案 0 :(得分:2)

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

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

lsof

lsof | grep "can't identify protocol"

您将得到如下结果:

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

请注意类型sock和名称can't identify protocol

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

  

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

     

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

  COMMAND PID ... TYPE ... NODE NAME
  pump    226 ... sock ...  309 can't identify protocol
     

这意味着它无法识别协议(即AF_ *   名称)由打开的套接字文件使用。 Lsof识别   通过匹配与   / proc // fd条目,以找到在   / proc / net子目录。

     

...

     

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

验证过程

lsof输出中的PID为29644。

ls -l /proc/29644/fd   

结果为:

...
lrwx------ 1 stephan stephan 64 Jul  7 22:52 11 -> socket:[312064]
lrwx------ 1 stephan stephan 64 Jul  7 22:52 12 -> socket:[312066]
...

grep 312066 /proc/net/*

给出空结果。