2012-07-05 61 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