sas*_*trn 6 java tcp apache-mina
对我来说这看起来很奇怪.我可以在同一个端口上运行多个TCP服务器.
我使用Apache MINA库和以下代码:
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.bind(new InetSocketAddress(80));
Run Code Online (Sandbox Code Playgroud)
端口80已被其他程序使用.但我没有得到异常"地址已经在使用中".使用netstat,我可以看到以下内容:
C:\>netstat -oan |find /i "LIST"
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 2220
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 904
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 840
Run Code Online (Sandbox Code Playgroud)
有人可以解释我这样的行为吗?
操作系统:Windows 7.
谢谢.
通常,在 Windows 或任何其他操作系统(至少是主要操作系统)上,只有一个进程可以侦听 TCP 端口。在 Windows 上,如果两个进程共享端口,您可能会收到错误代码 10048。如果进程绑定到不同的接口地址,则这一点不适用(即使一个进程绑定到一个INADDR_ANY特定地址,另一个绑定到特定地址,它们也不会冲突)。SO_REUSEADDR此外,如果已在第二个套接字上设置,则这不适用。
然而,由于两个进程都是绑定的INADDR_ANY,并且您声称您的进程尚未SO_REUSEADDR设置,所以这是一个难题。据我所知,有三种可能性:
SO_REUSEADDR默认设置的。SO_REUSEADDR.我意识到没有软件是完美的,但我真的很犹豫是否选择第三个选项,特别是如果你可以轻松地重现它。我建议netstat在开始进程之前和之后仔细观察输出,并查看在此之前是否存在其他侦听器。另外,尝试识别其他进程并查看它是否相关(您可以为此启用任务管理器中的 PID 列)。
编辑
\n\n下面的评论者提醒我,我应该指出,SO_REUSEADDR不同平台的行为确实有所不同。Windows 允许新套接字使用该选项强制绑定到与其他侦听套接字相同的端口,如果两个套接字都是 TCP,则行为不确定,如此处所述。实际上,第二个套接字可能“窃取”地址,但官方说法似乎是该行为未定义:
\n\n\n一旦第二个套接字成功绑定,绑定到该端口的所有套接字的行为都是不确定的。例如,如果同一端口上的所有套接字都提供 TCP 服务,则无法保证通过该端口的任何传入 TCP 连接请求都由正确的套接字 \xe2\x80\x94 处理,该行为是不确定的。
\n
如果旧的 TCP 套接字仍在侦听,Linux(和其他 Unix 变体)将不允许两个 TCP 套接字共享同一端口。在这种情况下,SO_REUSEADDR仅当旧套接字处于 TIME_WAIT 状态时才允许新套接字绑定(也许是 FIN_WAIT 和 CLOSE_WAIT 状态,我必须检查这一点)。
顺便说一句,当我第一次在 Windows 中遇到它时,我发现行为上的差异非常令人惊讶,但我自己测试过它,当然如果你在SO_REUSEADDR两个套接字上进行设置,它很可能成功绑定到完全相同的套接字地址和端口同时进行。然而,我还没有对这种情况下的确切行为进行广泛的测试,因为就我而言,这并不重要。
我不打算讨论哪个平台是“正确的”,但 Windows 行为肯定会导致安全问题,这就是为什么他们提出了SO_EXCLUSIVEADDRUSE阻止其他套接字强制绑定的选项。我似乎还认为 Windows 版本应该被视为一个完全不同的选项,具有不同的行为,只是碰巧具有相同的名称。
| 归档时间: |
|
| 查看次数: |
1462 次 |
| 最近记录: |