【发布时间】:2018-11-23 17:42:10
【问题描述】:
当我使用 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);
}
}
当我绑定一个套接字时,不要将它与连接或监听一起使用。 我进入 /proc/[java task id]/fd ,发现这个socket的inode是“socket:[3073501]” 但即使在 /proc/net/tcp 或 /proc/net/tcp6 中我也找不到 inode 或端口
有什么方法可以找到绑定socket但不监听或连接的进程。
谢谢。
我看到了 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;
}
它只显示正在侦听或从 tcp_hashinfo 建立的袜子。但是 tcp_hashinfo 有三个结构
struct inet_bind_hashbucket *bhash;
struct inet_listen_hashbucket listening_hash[INET_LHTABLE_SIZE];
struct inet_ehash_bucket *ehash;
bhash 可用于绑定。 但是不会在 /proc/net/tcp 中导出。
【问题讨论】:
-
哇。我可以完全按照描述重现这个问题,这不是与
/proc/net/tcp样式十六进制表示法或基于/etc/services的名称的简单混淆。我也找不到lsof的端口号。nc -l仍然说它正在使用中,与发布的完全一样。 -
简单的解决方案是不要写那样的代码,确定吗?通常你会立即连接
Socket,而且绑定它通常没什么意义。 -
@jww 令人惊讶的是,这些都不适用