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

使用.net,我注意到试图连接到一个未被侦听的端口总是需要一秒钟。 要检查.net抽象是否是一个问题,或者是否是一个较低级别的问题,并将其与Linux(其中一个不成功的telnet类似3ms),我用一个node.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地址,结果与上面显示的localhost类似
  • 在node.js的情况下和我写的方式,(asynchronous)连接尝试并行运行,但在.net的情况下,我正在同步testing,即一个在另一个尝试,结果是一样的:每次1秒

任何想法,为什么Windows在这里缓慢? 这是一种蓄意的节stream吗?

HarryJohnston的评论让我改写了这个程序

如果另一个程序在那个一秒的延迟期间开始监听那个端口,会发生什么情况

看起来, 在Windows上,connect()调用尝试以500毫秒的间隔最多连接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);