windows - 为什么在 Windows 上尝试 Socket.connect 失败需要 1 秒?

标签 windows tcp connection

使用 .net 时,我注意到尝试连接到未监听的端口总是需要 1 秒。为了检查这是 .net 抽象中的问题还是较低级别的问题,并将其与 linux 进行比较(不成功的 telnet 需要大约 3ms),我使用了一个节点。连接端口的js脚本

  • 12345,没有进程监听的端口
  • 80,正在监听的端口

Windows 的结果:

Connecting to 127.0.0.1:12345
#3: error elapsed: 1000ms, Error: connect ECONNREFUSED
#2: error elapsed: 1002ms, Error: connect ECONNREFUSED
#4: error elapsed: 1003ms, Error: connect ECONNREFUSED
#1: error elapsed: 1007ms, Error: connect ECONNREFUSED
#0: error elapsed: 1015ms, Error: connect ECONNREFUSED

Connecting to 127.0.0.1:80
#0: connect elapsed: 8ms
#1: connect elapsed: 1ms
#2: connect elapsed: 3ms
#3: connect elapsed: 4ms
#4: connect elapsed: 6ms

Linux 的结果:

Connecting to 127.0.0.1:12345
#4: error elapsed: 0ms, Error: connect ECONNREFUSED
#3: error elapsed: 1ms, Error: connect ECONNREFUSED
#2: error elapsed: 1ms, Error: connect ECONNREFUSED
#1: error elapsed: 1ms, Error: connect ECONNREFUSED
#0: error elapsed: 3ms, Error: connect ECONNREFUSED

Connecting to 127.0.0.1:80
#4: connect elapsed: 0ms
#3: connect elapsed: 0ms
#2: connect elapsed: 0ms
#1: connect elapsed: 1ms
#0: connect elapsed: 2ms

Node.js 来源:

var net = require('net');
var host = process.argv[2];
var port = Number(process.argv[3]);
console.log("Connecting to %s:%d", host, port);
for (i = 0; i < 5; i++)
{
  (function(i) {
    var date = +new Date;
    var client = net.connect({host: host, port: port});
    client.on('error', function(msg)
    {
      console.log("#%d: error elapsed: %dms, %s", i, new Date - date, msg);
    });
    client.on('connect', function()
    {
      console.log("#%d: connect elapsed: %dms", i, new Date - date);
    });
  })(i);
}

一些注意事项

  • 我也尝试了远程 IP 地址,结果类似于上面显示的本地主机
  • 在 node.js 的情况下以及我编写它的方式中,(异步)连接尝试并行运行,但在 .net 的情况下,我正在同步测试,即一个接一个的尝试,结果是相同:每次 1 秒

知道为什么 Windows 在此处运行缓慢吗?这是某种故意节流吗?

最佳答案

@HarryJohnston的评论引导我重写程序看看

what happens if another program starts listening on that port during that one second delay

看起来,在 Windows 上,对 connect() 的调用尝试以 500 毫秒的间隔最多连接到未绑定(bind)端口 3 次。如果第三次尝试也失败,它就会放弃。

这是测试运行的日志,我偶尔随机启动和停止一个监听端口 12345 的进程:

Connecting to 192.168.77.11:12345
#1: error elapsed: 1008ms, Error: connect ECONNREFUSED
#2: error elapsed: 1001ms, Error: connect ECONNREFUSED
#3: error elapsed: 1004ms, Error: connect ECONNREFUSED
#4: connect elapsed: 1001ms
#5: connect elapsed: 1000ms
#6: connect elapsed: 500ms
#7: error elapsed: 1000ms, Error: connect ECONNREFUSED
#8: connect elapsed: 1001ms
#9: error elapsed: 1000ms, Error: connect ECONNREFUSED
#10: connect elapsed: 500ms
#11: error elapsed: 1000ms, Error: connect ECONNREFUSED
#12: error elapsed: 1000ms, Error: connect ECONNREFUSED
#13: connect elapsed: 500ms
#14: error elapsed: 1000ms, Error: connect ECONNREFUSED
#15: connect elapsed: 500ms
#16: error elapsed: 1000ms, Error: connect ECONNREFUSED
#17: connect elapsed: 500ms
#18: connect elapsed: 1000ms
#19: connect elapsed: 1000ms
#20: connect elapsed: 500ms
#21: connect elapsed: 1011ms
#22: connect elapsed: 1000ms
#23: error elapsed: 1000ms, Error: connect ECONNREFUSED

以及修改后的源码:

var net = require('net');
var host = process.argv[2];
var port = Number(process.argv[3]);
console.log("Connecting to %s:%d", host, port);
var connect = function(i) {
    var date = +new Date;
    var client = net.connect({host: host, port: port});
    client.on('error', function(msg)
    {
      console.log("#%d: error elapsed: %dms, %s", i, new Date - date, msg);
      connect(i + 1);
    });
    client.on('connect', function()
    {
      console.log("#%d: connect elapsed: %dms", i, new Date - date);
      connect(i + 1);
    });
  };
connect(1);

关于windows - 为什么在 Windows 上尝试 Socket.connect 失败需要 1 秒?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19440364/

相关文章:

windows - 如何将自定义文件系统添加到 Window 的格式数据对话框的列表中?

windows - 如何在 Windows 10 上使 wsl2 从停止状态变为运行状态

c# - Android 客户端与通用 Windows 平台之间的 TCP 通信

java - 使用 java 中的代理代码连接到站点

c++ - 如何正确关闭与 Poco::HTTPSClientSession 的连接?

windows - 有没有办法自动更改 <link> , &lt;script&gt; 标签中的文件名

c++ - Libpurple 无法连接 - Purple_presence_is_online 失败

c - 哪种是实现 TCP/UDP 服务器的最佳方式?在线程或进程中处理每个传入请求

javascript - Node.js websockets 使用 UDP 或 TCP

c# - 连接数据库时c#中的constring错误