如何在不设置 SO_REUSEPORT 的情况下使 nc 监听端口

DWi*_*hes 6 port tcpip netcat socat

我想让一个nc命令监听 TCP 端口,所以我这样做了:

nc -lv 8888
Run Code Online (Sandbox Code Playgroud)

然后在另一个控制台中,我检查尝试侦听同一端口的另一个程序是否会收到某种Address already in use类型的错误,因此我再次发出相同的命令:

nc -lv 8888
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是第二个命令也成功了。研究两个程序如何在同一个 TCP 端口上侦听,我发现如果使用选项打开侦听套接字SO_REUSEPORT,这是可能的,所以我 nc正在使用它。

如何禁止nc其他程序使用其同一端口?我希望它侦听端口 8888 并确保这是唯一侦听该端口的程序。

到目前为止,我已经能够通过这样的介绍来完成我想做的socat事情nc

socat TCP-LISTEN:8888,fork TCP:localhost:4444
nc -lv 4444
Run Code Online (Sandbox Code Playgroud)

因为socat不允许任何其他程序侦听同一端口。

但仅用 就可以实现这一点吗nc

小智 5

查看netcat源代码netcat.c中的方法之一local_listen

        ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
        if (ret == -1)
            err(1, NULL);

# if defined(SO_REUSEPORT)
        ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
        if (ret == -1)
            err(1, NULL);
# endif
Run Code Online (Sandbox Code Playgroud)

然后为了修改行为,您需要修改代码。

不过,我使用 Ubuntu Xenial 的 netcat-openbsd 1.105-7 进行了测试,它似乎是在没有定义 SO_REUSEPORT 的情况下构建的。由于它设置了 SO_REUSEADDR 而不是 SO_REUSEPORT(在内核 > 3.9 下),它的工作方式就像您期望拒绝在同一端口上运行第二个实例一样。