Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在c语言中关闭tcp套接字连接#_C#_Sockets_Tcp - Fatal编程技术网

C# 如何在c语言中关闭tcp套接字连接#

C# 如何在c语言中关闭tcp套接字连接#,c#,sockets,tcp,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() {

我有一个来自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
()


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

在本例中,您将从
NetworkStream
对象收到一个
System.IO.IOException
。此异常的嵌套值为10054(=
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();

使用
try..catch
block。当我启动连接并终止客户端时,我在服务器端的“case SocketError.ConnectionReset:txtLog.Text+=Environment.NewLine+”发生了连接重置SocketException。”;中断;'跨线程操作无效:从创建控件“txtLog”的线程以外的线程访问控件“txtLog”。只能在创建控件的线程上访问控件。我没有将
txtLog
作为控件进行连接。将其添加到匿名线程委托中是问题的根源。请给我一点时间,找一篇关于这个问题的文章。我认为您可以将整个catch块放在对
txtLog.Invoke((MethodInvoker)委托{/*catch块here*/})的调用中作为快速解决方案。