2012-07-05 38 views
0

很久以前我做了使用这段代码的原则(IP地址和端口的constans是仅用于测试)基于套接字服务器应用程序:奇怪的插座行为2008

... 
    _mainSocket = new Socket(AddressFamily.InterNetwork, 
          SocketType.Stream, ProtocolType.Tcp); 

    _mainSocket.SetSocketOption(SocketOptionLevel.IP, 
           SocketOptionName.ReuseAddress, 1); 

    IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("192.168.1.103"), 77); 

    _mainSocket.Bind(endPoint); 

    _mainSocket.Listen(5); 

    _mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null); 
    ... 

它的工作几年前,直到最近,客户在Windows Server 2008计算机上安装该服务并尝试从其他网络(即通过一个或多个路由器)连接到该服务器。

令人惊讶的是,这是不可能的!

进一步分析发现,根本原因是TTL时间到现场参数在IP数据包头)被设定成从我服务的所有应答报文,有效地导致它们成为掉到他们遇到的第一台路由器上。

有趣的是,如果我删除了SetSocketOption(...)调用,那么TTL会回到128个!

这种奇怪的行为似乎只是Windows Server 2008的情况.Windows XP和Windows 7保持在TTL = 128上,正如我所期望的那样。我根本没有看到为什么TTL应该使用“重新使用地址”选项进行更改。谁能解释一下?

我还可以得到TTL回128后的第一个加入 SetSocketOption(...)电话:

_MainSocket.SetSocketOption(SocketOptionLevel.IP, 
          SocketOptionName.DontRoute, 0). 

这有效地中和了第一SetSocketOption的不良副作用(。 )电话...

请告诉我,我在这件事上似乎并不了解?

Martin。

回答

1

这Blurb的MSDN的页面上张贴SocketOptionName似乎有点启发,虽然我还没有证实它:

误区与.NET 反射使用红门的.NET阅读.NET框架的源代码时反射器解码在.NET框架 2.0类Socket ...

...

这是为什么ReuseAddress代替IpTimeToLive?

事实上:

SocketOptionName.IpTimeToLive == == SocketOptionName.ReuseAddress 4

如果这是某种情况下,这将解释为什么TTL是越来越设置为1 - 这就是你传递给ReuseAddress的价值。

+0

你似乎是点!的确,** IpTimeToLive **和** ReuseAddress ** _both_的值都是4.但是,为了让系统将4解释为** ReuseAddress **,必须使用_SocketOptionLevel.Socket_ - 如果他使用_SocketOptionLevel。IP_,它被解释为** IpTimeToLive **!结论:我犯了一个编程错误,MS做得很好(幸运的是!)。 – 2012-07-05 12:55:27