在Windows 7中如何让两个进程监听同一个端口?

9

我正在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 告诉我端口已经被占用。)那么...

  1. 为什么/如何会出现这种情况?在某些情况下,这个行为有用吗?
  2. 如果另一个应用程序要捕获传入的请求,我不希望实例成功运行... 我该如何使端口独占?
1个回答

8

如果使用标志SO_REUSEADDR打开套接字,这是TCP套接字应用程序中常见的操作。

通常,SO_REUSEADDR用于以下两种情况之一:

  1. 当进程崩溃、被杀死或强制重新启动而没有机会关闭其套接字时。或者进程已退出但套接字(或子连接套接字)仍处于FIN_WAIT或FIN_WAIT2状态。第二个进程可以打开套接字而不会得到“已在使用中”的错误代码。我已经阅读了几篇关于TCP套接字最佳实践的S.O.帖子,建议这样做。

  2. 同一服务器程序分叉或同时运行多次。这允许负载均衡而无需编写使用线程的服务器程序。通常,“其他实例”监听套接字上的程序将接受传入的连接,而第一个则忙于另一个连接。

关于您的第二个问题,最简单的方法是不使用SO_REUSEADDR。如果您担心可能会有一个恶意应用程序尝试使用SO_REUSEADDR,则您的应用程序可以使用SO_EXCLUSIVEADDRUSE。(这是一个标志,基本上表示“不允许其他应用程序使用SO_REUSEADDR打开相同的端口。”)

谢谢,我一开始以为这个标志和同名的UNIX标志完全一样。MSDN网站真是启发人:http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621(v=vs.85).aspx - Olson
有关SO_REUSEADDR和许多平台上相关标志的详细讨论,请参见https://dev59.com/rWYq5IYBdhLWcg3wjBQM。 - Aerom Xundes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接