0

ずっと前に、このコードの原則を使用してソケットベースのサーバーアプリケーションを作成しました(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 マシンにサービスをインストールし、別のネットワークから (つまり、1 つまたは複数のルーターを介して) サービスに接続しようとした最近まで、これは何年もうまく機能していました。

驚くべきことに、これは不可能でした!

さらに分析した結果、根本的な原因は、サービスからのすべての応答パケットでTTL ( IP パケット ヘッダーの Time-To-Liveパラメータ) が1に設定されていることであり、最初に出会ったルーターで事実上それらがドロップされる原因となっていることが明らかになりました。

面白いことに、SetSocketOption(...)呼び出しを削除すると、TTL は通常の 128 に戻ります!

この奇妙な動作は、Windows Server 2008 の場合にのみ発生するようです。Windows XP と Windows 7 の両方が、予想どおり TTL=128 のままです。「ReuseAddress」オプションで TTL を変更する必要がある理由がまったくわかりません。誰でも説明できますか?

最初の呼び出しの後に 2 つ目の SetSocketOption(...) 呼び出しを追加することで、TTL を 128 に戻すこともできます。

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

これにより、最初の SetSocketOption(..) 呼び出しの望ましくない副作用が効果的に中和されます...

この件で私が理解していないように見えることを教えてください。

マーティン。

4

1 に答える 1

1

MSDN のページに投稿されたこの宣伝文句は、SocketOptionName確認していませんが、やや明るいようです。

.NET Framework のソースコードを .NET Reflector で読むときの誤解 Red Gate の .NET Reflector を使用して、.NET Framework v2.0 でクラス Socket をデコードする...

...

なぜ IpTimeToLive ではなく ReuseAddress なのですか?

実際には:

SocketOptionName.IpTimeToLive == SocketOptionName.ReuseAddress == 4

これが何らかの形で当てはまる場合、TTLが に設定された理由を説明1できます。これは、 に渡す値ですReuseAddress

于 2012-07-05T11:00:44.287 に答える