繁体   English   中英

如何检查是否已在侦听TCP端口?

[英]How do I check if a TCP port is already being listened on?

我有一个第三方库充当HTTP服务器。 我传递了一个地址和端口,然后用它来监听传入的连接。 此库以这样的方式进行侦听,即它不会接收端口的唯一用法以及它所绑定的地址。 结果,我可以多次在同一个端口上侦听。

我需要在同一个进程中运行此HTTP服务器的多个实例。 每个实例都有一个默认端口,但如果该端口不可用,则应使用下一个可用端口。 这是我的问题所在; 我最终可以在同一个端口上监听两个HTTP服务器。

我无法更改HTTP服务器的代码,如果无法侦听我提供的端口,HTTP服务器将不会提醒我,因此我必须能够在启动每个HTTP服务器之前检查端口是否已在使用中。 我已经尝试通过绑定自己的套接字来检查端口是否已被监听,SO_REUSEADDR设置为FALSE且SO_EXCLUSIVEADDRUSE设置为TRUE,但是当现有HTTP服务器已经在该端口上侦听时,绑定和侦听调用都成功。

该HTTP服务器如何实现此效果,如何以这种方式准确检查是否正在侦听端口?

快速而脏的方法是尝试connect()到localhost上的端口。 如果connect()调用成功,那么您知道当前正在侦听端口(由接收连接的任何人)。 如果连接调用失败(特别是使用ECONNREFUSED ),那么您可以非常确定没有人正在侦听该端口。

当然,这里有一个竞争条件:在你运行上述测试后,没有什么能够阻止另一个程序突然进入并抓住端口,但是在你自己绑定到端口之前。 因此,您应该将测试结果视为一个提示而不是绝对规则,并且(希望)如果您稍后发现该端口正在使用中,那么(希望)有一些方法可以处理它。

使用端口号0.操作系统将选择一个空闲端口。

http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621(v=vs.85).aspx解释了不同选项如何相互作用。

您没有向我们提供足够的信息来告诉我们您的用例中究竟发生了什么,但我可以通过一个看起来像您所看到的任意用例。

假设您使用的是Win 2003或更高版本,主NIC是10.0.0.1,并且所有内容都在同一个用户帐户下运行。

您的应用程序的第一个实例出现,您的测试代码尝试使用SO_EXCLUSIVEADDREUSE绑定10.0.0.1:12345。 当然这很有效。

关闭套接字,然后告诉HTTP服务器监听端口12345.它使用SO_REUSEADDR绑定0.0.0.0:12345,这当然有效。

现在,您的应用程序的第二个实例出现,您的测试代码尝试使用SO_EXCLUSIVEADDREUSE绑定10.0.0.1:12345。 根据MSDN文章中的图表,这是有效的。

你关闭套接字,然后告诉HTTP服务器监听端口12345.它绑定0.0.0.0:12345与SO_REUSEADDR,它的工作原理。

如果这是问题,假设您无法让HTTP服务器绑定特定地址,您可以在测试代码中使用0.0.0.0来解决问题。 (当然,如果它是其他数百个可能出现的问题之一,那么该解决方案将无效。)

如果您不知道HTTP服务器正在使用哪些套接字选项,地址等,并且没有源,则只需在调试器中运行它并断开相关调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM