我在Windows 7中运行两个stunnel实例,配置为侦听同一个端口,看起来它们都在同一端口上成功侦听(只使用socket()/ bind()/ listen()) 。两个实例似乎都成功通过所有调用,并且它们显示在netstat中:
C:\>netstat -ano | grep 8000
TCP 0.0.0.0:8000 0.0.0.0:0 LISTENING 5828
TCP 0.0.0.0:8000 0.0.0.0:0 LISTENING 5852
第一个收听的人获取所有传入的请求。
这与我的所有期望完全相反。 (我当时希望让EADDRINUSE告诉我港口很忙。)所以.......
答案 0 :(得分:7)
如果使用标志SO_REUSEADDR打开套接字,则可以实现这一点,这对于TCP套接字应用程序来说并不罕见。
通常,SO_REUSEADDR用于以下两种情况之一:
当进程崩溃,被杀或被强行重启而没有机会关闭其套接字时。或者进程退出但套接字(或子连接套接字)仍处于FIN_WAIT或FIN_WAIT2状态。第二个进程可以在不获取“已使用”错误代码的情况下打开套接字。我在S.O.上看过几篇文章。建议这是TCP套接字的最佳实践。
同一服务器程序可以同时分叉或运行多次。这允许在没有编写服务器程序的情况下进行负载平衡以利用线程。通常,在第一个忙于另一个连接时,监听套接字的程序的“其他实例”将接受传入连接。
关于第二个问题,最简单的方法是不使用SO_REUSEADDR。如果您担心可能存在尝试使用SO_REUSADDR的流氓应用,那么您的应用可以使用SO_EXCLUSIVEADDRUSE。 (一个标志,基本上说,“不允许其他应用程序使用SO_REUSEADDR打开同一个端口。)