Long time ago I made a socket based server application using the principle of this piece of code (IP address and port constans are only for testing):
...
_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);
...
It has worked well for years, until recently, when a customer installed the the service on a Windows Server 2008 machine and tried to connect to it from antoher network (i.e. through one or more routers).
Surprisingly this was not possible!
Further analysis revealed that the root cause was TTL (Time-To-Live parameter in IP packet headers) being set to 1 in all reply packets from my service, effectively causing them to be to be dropped at the first router they meet.
The funny thing is, that if I remove the SetSocketOption(…) call, TTL gets back to the ususal 128!
This odd behavior seems only to be the case with Windows Server 2008. Both Windows XP and Windows 7 stays on TTL=128 as I would expect it to do. I see no reason at all why TTL should be changed with the “ReuseAddress” option. Can anyone explain?
I can also get TTL back to 128 by adding a second SetSocketOption(…) call after the first one:
_MainSocket.SetSocketOption( SocketOptionLevel.IP,
SocketOptionName.DontRoute, 0).
This effectively neutralizes the unwanted side effect of the first SetSocketOption(..) call…
Please tell me what I don’t seem to understand in this matter?
Martin.
This blurb posted on the MSDN page for
SocketOptionNameseems somewhat illuminating, although I haven’t confirmed it:If this is somehow the case, that would explain why the
TTLwas getting set to1— that’s the value you’re passing in forReuseAddress.