2016-09-17 65 views
1

當以下裸露代碼正在發送或接收數據時,客戶端將斷開連接。爲什麼要處理NetworkStream斷開客戶端

這是我的理解,一個使用塊放置它創建的對象,即NetworkStream對象,但爲什麼TcpClient套接字斷開?

控制檯輸出... 真 假

class Program 
    { 
     static void Main(string[] args) 
     { 
      Console.Title = "Client"; 

      Process p = Process.Start(@"C:\Users\Teddy\Documents\visual studio 2015\code\TesyingNetworkStream\Server\bin\Debug\server.exe"); 
      Thread.Sleep(1000); 

      IPEndPoint EP = new IPEndPoint(
        IPAddress.Parse("192.168.1.10"), 4000 
        ); 

      TcpClient cli = new TcpClient(); 
      cli.Connect(EP); 

      UseClient(cli); 

      Console.ReadLine(); 
      p.Kill(); 
      p.Close(); 
     } 

     private static void UseClient(TcpClient cli) 
     { 
      using (NetworkStream ns = cli.GetStream()) 
      { 
       Console.WriteLine(cli.Connected);//True 
      } 
      Console.WriteLine(cli.Connected);//False 
     } 
    } 

這裏是服務器端的代碼,如果它很重要。

class Program2 
    { 
     static void Main(string[] args) 
     { 
      Console.Title = "Server"; 

      TcpListener lis = new TcpListener(
       new IPEndPoint(
        IPAddress.Any, 4000 
        )); 

      lis.Start(); 

      lis.AcceptTcpClient(); 

      while (true) 
      { 
       Thread.Sleep(10); 
      } 
     } 
    } 

回答

3

這裏的GetStream()功能實現(從.NET framework source):

public NetworkStream GetStream() { 
    if (m_CleanedUp){ 
     throw new ObjectDisposedException(this.GetType().FullName); 
    } 
    if (!Client.Connected) { 
     throw new InvalidOperationException(SR.GetString(SR.net_notconnected)); 
    } 
    if (m_DataStream == null) { 
     m_DataStream = new NetworkStream(Client, true); 
    } 
    return m_DataStream; 
} 

注意true在調用構造函數NetworkStream。這是ownsSocket參數。從MSDN

如果ownsSocket參數的值是true,所述的NetworkStream取 所有權底層套接字的,並調用Close方法還 關閉底層插槽。

NetworkStreamDispose實施Close的流,然後關閉套接字。

1

這是因爲cli.GetStream();不會創建一個新的流每次調用它的時候,有一個連接,每次調用cli.GetStream();返回相同的流對象的單個流。當你處理那個發送給TcpClient的共享流時,你已經完成了,它標記出TcpClient已經斷開。