【问题标题】:Cannot connect to a local port anymore that is still being listened by a process无法再连接到仍在被进程侦听的本地端口
【发布时间】:2015-05-21 04:46:59
【问题描述】:

我有一个服务器应用程序 (unimrcpserver.exe) 正在响应来自客户端进程的请求。此服务器进程侦听多个端口。 使用netstat -a 命令,我的进程得到以下几行。

  TCP    192.168.10.65:2544     MERTB-PC:0             LISTENING  
  TCP    192.168.10.65:2554     MERTB-PC:0             LISTENING  
  TCP    192.168.10.65:9060     MERTB-PC:0             LISTENING  

(netstat输出很长我这里只放相关行)

通常,当系统工作时,我会从这些端口向服务器发出请求,并且每个端口都可以正常工作。

当我进行压力测试时,我看到系统不再响应我通过端口 2554 发出的请求。 netstat -a 仍然给了我上面的行,所以服务器仍然在监听这个端口。当我在同一台机器上运行 telnet 时出现错误:

telnet 192.168.10.65 2554  
  Connecting To 192.168.10.65...Could not open connection to the host, on port 2554: Connect failed

我还用 c++ 编写了一个简单的程序,以获取系统为 connect() 请求生成的确切错误消息。这次我收到以下错误:

No connection could be made because the target machine actively refused it

附加信息:一切都在同一台 Windows 机器上。防火墙被禁用。当我进行同时发送多个请求的压力测试时,这种情况只发生过一次。在这种情况发生之前,系统处理了大约 13000 个请求,大约需要半个小时。

所以问题是:这种情况怎么会发生?该端口被 netstat 报告为“正在侦听”,但我无法连接到它。如果它可能是由编程错误引起的,那么什么样的错误会导致这种行为?

【问题讨论】:

  • 也许有一个程序监听了这些端口但没有“清除”它们就关闭了?
  • 看起来不可能。这是我自己的工作站。我总是运行这些类型的测试,并且从未在这台机器上看到使用相同端口的另一个应用程序。
  • 然后检查可以使用这些端口的程序。你可以运行ps ax | grep 2544
  • 查看listen调用的backlog参数,应该是大了。或者您可能无法足够快地接受传入的连接...
  • @ForceBru 这是一台 Windows 机器。我用 netstat -a 检查过,没有其他程序在使用这个端口。

标签: c++ sockets tcp


【解决方案1】:

所以问题是:这种情况怎么会发生?该端口被报告>>为 netstat 的“LISTENING”,但我无法连接到它。如果它可能是由编程错误引起的,那么什么样的错误会导致这种行为?

是的,这可能是由服务器上的编程错误引起的。当服务器的侦听线程死锁时,我已经看到它发生了。套接字的状态是“正在侦听”,但如果侦听线程具有某种全局状态并且在等待释放互斥锁的其他线程上被阻塞,您将遇到这种情况。 此外,就像这里的其他人所说,如果由于压力测试而加载了 CPU,这可能会导致服务器拒绝连接,因为线程可能正忙于处理并且侦听线程永远没有机会接受连接。

【讨论】:

  • 似乎是正确的答案,但雷米更快。 :) 谢谢。
  • 另一种可能性是监听线程可能已经崩溃而不是死锁。
【解决方案2】:

在以下几种情况下可以“主动拒绝”新连接:

  1. IP:Port 上没有LISTENING 套接字。

  2. 有一个LISTENING套接字,但它的待处理连接积压已满,所以此时它无法接受新连接。

  3. 防火墙阻止了它。尽管防火墙更可能使用不同的错误,但如果它完全发送错误的话。

由于有一个LISTENING 套接字,#2 是最可能/最常见的情况。如果是这样,这意味着服务器应用程序没有足够快地从其积压中接受客户端(如果有的话)。

客户无法区分这些条件。它所能做的就是检测连接失败 - WSAECONNREFUSED 或 ECONNREFUSED,具体取决于平台 - 稍后再试。

【讨论】:

  • 嗯,所以套接字处于 LISTENING 状态。但是负责接收传入连接的线程已经以某种方式陷入僵局。这会导致由 SOMACONN 确定大小的传入连接队列被填满。这解释了我认为的情况。
猜你喜欢
  • 1970-01-01
  • 2014-04-28
  • 2019-06-23
  • 1970-01-01
  • 2016-10-23
  • 1970-01-01
  • 2023-01-26
  • 2019-07-10
  • 1970-01-01
相关资源
最近更新 更多