开发者

Accepting a socket on Windows 7 takes more than a second

Here's what I've done:

  • I wrote a minimal web server (using Qt, but I don't think it's relevant here).
  • I'm running it on a legal Windows 7 32-bit.

The problem:

  • If I make a request with Firefox, IE, Chrome or Safari it takes takes about one second before my server sees that there is a ne开发者_如何学JAVAw connection to be accepted.

Clues:

  • Using other clients (wget, own test client that just opens a socket) than Firefox, IE, Chrome, Safari seeing the new connection is matter of milliseconds.
  • I installed Apache and tried the clients mentioned above. Serving the request takes ~50ms as expected.
  • The problem isn't reproducible when running Windows XP (or compiling and running the same code under Linux)
  • The problem seems to present itself only when connecting to localhost. A friend connected over the Internet and serving the connection was a matter of milliseconds.
  • Running the server in different ports has no effect on the 1 second latency

Here's what I've tried without luck:

  • Stopped the Windows Defender service
  • Stopped the Windows Firewall service

Any ideas? Is this some clever 'security feature' in Windows 7? Why isn't Apache affected? Why are only the browsers affected?


If you're saying "localhost" instead of "127.0.0.1", you're forcing a name lookup before the actual connection attempt, adding delay.

In addition, some browsers, like Firefox 3.5+, don't use the operating system's DNS lookup mechanism, which is why it can have different performance than, say, wget.


You may be running into some automatic proxy discovery problem. In Firefox, you can disable this in Options | Advanced | Network | Settings; select either "No proxy" or give it explicit values. There's also the Internet Properties control panel, which is IE's network settings, but other browsers on Windows may obey settings here, too. Again, disable auto-proxy discovery. This can speed connections outside localhost, too.


For some reason Windows 7 takes 1 second to resolve address localhost regardless of it being in hosts file.

Adding localhost1 to hosts file and using that works around the problem.


When connecting to localhost on a IPv4/IPv6 dual stack host:

  • A DNS lookup is performed for localhost.
  • The DNS server (whether IPv6 enabled or not - this doesn't matter) returns both the AAAA record ::1, and the A record 127.0.0.1.
  • The client first attempts to connect to ::1.
  • We assume your server program is not IPv6-capable, which is a common case - due to historical reasons, many servers bind their socket to 0.0.0.0 by default rather than [::].
  • Here an ECONNREFUSED error would be raised for the client. This happens immediately on most platforms; on Windows however, a single call to connect() would try 3 times in 500ms intervals before giving up, hence taking a bit more than one second (See http://stackoverflow.com/q/19440364 for more details).
  • The client then creates a connection to 127.0.0.1 instead.

This would explain all your clues above:

  • If you make a request with Firefox, IE, Chrome, Safari or any other IPv6-capable clients, it takes takes about one second trying for ::1 before connecting to 127.0.0.1.
  • Your own test client just opens a INET socket, so it won't try ::1 at all.
  • Using a dual-stack server such as Apache, the clients will connect to ::1 happily.
  • The problem isn't reproducible on Windows XP, of which IPv6 support is not enabled by default.
  • The problem seems to present itself only when connecting to localhost, as your friend connected with an IPv4-only network.
  • Running the server in different ports has no effect on the 1 second latency.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜