2014-01-18 197 views
0

我從YouTube上的這個TCP套接字聊天應用如何關閉在C#中的TCP套接字連接

服務器端

int i; 
TcpListener server = new TcpListener(IPAddress.Any, 1980); 
NetworkStream stream; 
TcpClient client; 
byte[] datalength = new byte[4]; 

public Form1() 
{ 
    InitializeComponent(); 
} 

public void ServerReceive() 
{ 
    stream = client.GetStream(); 
    new Thread(() => 
    { 
     while ((i = stream.Read(datalength, 0, 4)) != 0) 
     { 

      byte[] data = new byte[BitConverter.ToInt32(datalength, 0)]; 
      stream.Read(data, 0, data.Length); 
      this.Invoke((MethodInvoker)delegate 
      { 
       txtLog.Text += System.Environment.NewLine + "Client : " + Encoding.Default.GetString(data); 
      }); 
     } 
    }).Start(); 

} 

public void ServerSend(string msg) 
{ 
    stream = client.GetStream(); 
    byte[] data; 
    data = Encoding.Default.GetBytes(msg); 
    int length = data.Length; 
    byte[] datalength = new byte[4]; 
    datalength = BitConverter.GetBytes(length); 
    stream.Write(datalength, 0, 4); 
    stream.Write(data, 0, data.Length); 
} 

private void btnSend_Click(object sender, EventArgs e) 
{ 
    try 
    { 
     if (client.Connected) 
     { 
      ServerSend(txtSend.Text); 
     } 
    }catch 
    { 
     txtLog.Text += "connection close"; 
    } 
} 

private void btnListen_Click(object sender, EventArgs e) 
{ 
    server.Start(); 

    new Thread(() => 
    { 
     client = server.AcceptTcpClient(); 

     if (client.Connected) 
     { 
      ServerReceive();      
     } 
    }).Start(); 

} 

客戶端

int i; 
TcpClient client; 
NetworkStream stream; 
byte[] datalength = new byte[4]; 

public Form1() 
{ 
    InitializeComponent(); 
} 

public void ClientReceive() 
{ 

    stream = client.GetStream(); 
    new Thread(() => 
     { 
      while ((i = stream.Read(datalength, 0, 4)) != 0) 
      { 

       byte[] data = new byte[BitConverter.ToInt32(datalength, 0)]; 
       stream.Read(data, 0, data.Length); 
       this.Invoke((MethodInvoker)delegate 
       { 
        txtLog.Text += System.Environment.NewLine + "Server : " + Encoding.Default.GetString(data); 
       }); 
      } 
     }).Start(); 

} 

public void ClientSend(string msg) 
{ 
    stream = client.GetStream(); 
    byte[] data; 
    data = Encoding.Default.GetBytes(msg); 
    int length = data.Length; 
    byte[] datalength = new byte[4]; 
    datalength = BitConverter.GetBytes(length); 
    stream.Write(datalength, 0, 4); 
    try 
    { 
     stream.Write(data, 0, data.Length); 
    } 
    catch 
    { 
     stream.Dispose(); 
     client.Close(); 
    } 
} 

private void btnConnect_Click(object sender, EventArgs e) 
{ 

    try 
    { 
     client = new TcpClient("127.0.0.1", 1980); 
     ClientReceive(); 
     txtLog.Text += Environment.NewLine+ "Connected"; 

    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 

private void btnSend_Click(object sender, EventArgs e) 
{ 

    if (client.Connected) 
    { 
     ClientSend(txtSend.Text); 
    } 
} 

現在,所有這些作品的罰款我,但是每次我關閉一個他們,我得到這個錯誤 '無法從傳輸連接讀取數據:現有連接被遠程主機強行關閉。'在ClientReceive()或ServerReceive()

我應該如何捕捉這個錯誤,如果其中一個突然關閉或網線突然拔下?在此先感謝

+0

使用'try..catch'塊。 – CodeCaster

回答

0

在這種情況下,您收到來自NetworkStream對象的System.IO.IOException對象。該異常具有嵌套的System.Net.Sockets.SocketException和0125430056的10054(SocketErrorCode == ConnectionReset)。要處理異常,請使用try-catch塊。例如,

using System; 
using System.IO; 
using System.Net.Sockets; 

stream = client.GetStream(); 
new Thread(() => 
    { 
     try 
     { 
      while ((i = stream.Read(datalength, 0, 4)) != 0) 
      { 
       byte[] data = new byte[BitConverter.ToInt32(datalength, 0)]; 
       stream.Read(data, 0, data.Length); 
       this.Invoke((MethodInvoker)delegate 
       { 
        txtLog.Text += System.Environment.NewLine + "Server : " + Encoding.Default.GetString(data); 
       }); 
      } 
     } 
     catch (IOException ioex) 
     { 
      if (ioex.InnerException != null) 
      { 
       var sex = ex.InnerException as SocketException; 
       if (sex == null) 
       { 
        txtLog.Text += Environment.NewLine + "An unknown exception occurred."; 
       } 
       else 
       { 
        switch (sex.SocketErrorCode) 
        { 
         case SocketError.ConnectionReset: 
          txtLog.Text += Environment.NewLine + "A ConnectionReset SocketException occurred." 
          break; 
         default: 
          txtLog.Text += Environment.NewLine + "A SocketException occurred."; 
          break; 
        } 
       } 
      } 
      else 
      { 
       txtLog.Text += Environment.NewLine + "An IOException occurred."; 
      } 
     } 
    }).Start(); 
+0

當我開始連接並終止客戶端我在服務器端的'case SocketError.ConnectionReset: txtLog.Text + = Environment.NewLine +「發生了ConnectionReset SocketException發生。 break;'跨線程操作無效:從其創建線程以外的線程訪問控制'txtLog'。 –

+0

控件只能在創建它們的線程上訪問。我沒有把'txtLog'作爲控件的連接。在匿名線程委託中添加它是問題的根源。給我一點時間找到解決問題的SO帖子。 –

+0

http://stackoverflow.com/questions/661561/how-to-update-the-gui-from-another-thread-in-c?rq=1 –