2017-11-02 6 views
0

私のアプリには奇妙なエラーがあります:"各ソケットの1つの使用法 "address.IはtcpviewのCLOSE_WAITステータスで多くのソケットを見ました。TCPClient "各ソケットアドレスとlingerオプションの1つのみの使用

TcpListener listener = new TcpListener(IPAddress.Any, 7874); 
TcpClient client; 
listener.Start(); 

while (true) 
{ 
    client = listener.AcceptTcpClient(); 
    ThreadPool.QueueUserWorkItem(ThreadProc, client); 
} 


private static void ThreadProc(object obj) 
{ 
    var client = (TcpClient)obj; 
    client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(true, 0)); 
    var stream = client.GetStream(); 
    using(client){ 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      int numBytesRead; 
      byte[] data = new byte[1024]; 
      try 
      { 
       while ((numBytesRead = stream.Read(data, 0, data.Length)) > 0) 
       { 
        ms.Write(data, 0, numBytesRead); 
       } 
      }catch(Exception ex) 
      {} 
      var str = Encoding.ASCII.GetString(ms.ToArray(), 0, (int)ms.Length); 

     } 
    } 
} 

クライアント:

while (true) 
{ 
    try 
    { 

     using (TcpClient client = new TcpClient(obj.ToString(), 7874)) 

     { 
      client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(true, 0)); 
      var stream = client.GetStream(); 
      { 
       stream.Write(bytes, 0, bytes.Length); 

      } 

      Thread.Sleep(timeSleep); 
      //just trying all possible close 
      client.Client.Shutdown(SocketShutdown.Both); 
      client.Client.Close(0); 
      client.Close(); 
     } 
    }catch(Exception ex) 
    { 
     Console.WriteLine(ex); 
    } 
} 

が、通常のPythonクライアントワーク:

while True: 
    s = socket.socket(
     socket.AF_INET, socket.SOCK_STREAM) 
    try: 
     s.connect((addr, 7874)) 
     l_onoff = 1 
     l_linger = 0 
     s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, 
        struct.pack('ii', l_onoff, l_linger)) 
     s.send(b'test') 
     while True: 
      data =s.recv(1024) 
      break 
    except Exception as ex: 
     print(str(datetime.datetime.now())+'NS FAIL') 
    finally: 
     s.close() 
。それは サーバーの下に作業コードをdoesnの

は、.NET tcpclient ignore set lingerオプションのように見えます。同じ結果:

client.LingerState = new LingerOption(true, 0); 
+0

問題が確実に再現されていないと、良い回答が得られません。つまり、あなたが投稿したコードは、本当の優雅なシャットダウンを無視しているように見えます。 Shutdown()を呼び出すだけでは不十分です。各エンドポイントは、受信したデータの100%が受信されるように、受信が0バイトカウントを返すまで接続から受信する必要があります。これがなければ、ネットワーク層はしばらくの間ソケットを開いたままにしなければならない。正しく実行された場合、 'LINGER'オプションは必要ありません。 –

+0

このコードはすべて "client.Client.Shutdown(SocketShutdown.Both); client.Client.Close(0); client.Close();"テスト用です。標準的な処分は同じ問題を生み出す。ネットワーク層は、重いローディング中にライナーのタイムアウト時間のために常にCLOSE_WAITにソケットを残します。私の質問は:なぜネットはリンガータイムアウトを無視します。 C++/pythonは正常に動作します。ネットでのみ問題 – kain64b

答えて

0

私はあなたがLingerOptionを設定する必要はないと思います。私の推測では、サーバー側(受け入れられたクライアント)にクライアントソケットを配置しないで、ソケットスタックに割り当てられたままにすることです。

関連する問題