2014-01-18 196 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 –