如何在c#中关闭tc​​p套接字连接

时间:2014-01-18 18:12:39

标签: c# sockets tcp

我有来自youtube的这个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()

如果其中一个突然关闭或网络电缆突然拔出,我应该如何捕获此错误?提前谢谢

1 个答案:

答案 0 :(得分:0)

在这种情况下,您从System.IO.IOException对象收到NetworkStream。此例外有一个嵌套System.Net.Sockets.SocketExceptionErrorCode为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();