【发布时间】:2012-07-05 18:32:17
【问题描述】:
很早以前我就用这段代码的原理做了一个基于socket的服务器应用程序(IP地址和端口常量仅用于测试):
...
_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 数据包标头中的Time-To-Live 参数)被设置为 1来自我的服务的所有回复数据包,实际上导致它们在遇到的第一个路由器上被丢弃。
有趣的是,如果我删除 SetSocketOption(...) 调用,TTL 会恢复到通常的 128!
这种奇怪的行为似乎只适用于 Windows Server 2008。Windows XP 和 Windows 7 都保持 TTL=128,正如我所期望的那样。我完全看不出为什么应该使用“ReuseAddress”选项更改 TTL。谁能解释一下?
我还可以通过在第一个之后添加 second SetSocketOption(...) 调用将 TTL 恢复到 128:
_MainSocket.SetSocketOption( SocketOptionLevel.IP,
SocketOptionName.DontRoute, 0).
这有效地抵消了第一个 SetSocketOption(..) 调用的不良副作用...
请告诉我在这件事上我似乎不明白什么?
马丁。
【问题讨论】:
标签: c# .net windows sockets tcp