2017-12-20 9 views
0

サーバーでは、サーバーがクライアントからの接続を受け入れ、クライアント接続に関連付けられたソケットをシャットダウンすると、クライアントは引き続きサーバーにデータを送信できます。クライアントによって例外は発生しません。クライアントが閉じたサーバー側ソケットに依然として送信することがあります

このソケットをシャットダウンしないと、クライアント側で例外が発生するのはなぜですか?

私はクライアントが送信を試みることを期待していますが、サーバソケットに接続されなくなったことを認識して例外を発生させます。明らかに、これは起こっていません。これは、ソケットがここでどのように動作するかについての私の仮定が間違っているか(かなり可能)、または私のコードが間違っていることを意味します。 :-)

public async Task Demo() 
{ 
    var endPoint = new IPEndPoint(IPAddress.Loopback, 2100); 
    var serverTask = Task.Run(() => 
    { 
     using (var listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) 
     { 

      listenSocket.Bind(endPoint); 
      listenSocket.Listen(backlog: 1); 

      using (var connectionSocket = listenSocket.Accept()) 
      { 
       connectionSocket.Shutdown(SocketShutdown.Both); 
       connectionSocket.Close(); 
      } 
     } 
    }); 

    using (var clientSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) 
    { 
     clientSocket.Connect(endPoint); 

     await serverTask; 

     // Expect this to throw a SocketException--but it doesn't. 
     clientSocket.Send(new byte[] { 01 }); 
    } 
} 
+1

これはC#または.NETの質問ではありません。それはちょうどソケットがどのように働くか、そしてマークされた重複があなたが見るものを説明するかどうかについてです。短いバージョン:リモートエンドポイントが強制的に接続を切断すると、それを認識するために書き込み操作が行われます。あなたの最初の 'Send()'コールは、データをバッファリングするだけです。データが受信されたという保証はなく、エラーの報告は遅れることがあります。 –

答えて

0

ソケットクローズは「bang !!!」ではありません。インスタントアクション。 shutdown/closeを呼び出すだけで、接続を終了する意図が示されます。実際の切断は、任意の時間が経過した後に起こります(ループバック接続の場合、多くのことに依存します)。

以下を試してください。Send()をwhile(true)ループにラップしてください。あなたの最初の反復はOKであり、SocketExceptionで終了します。

関連する問題