0
votes

I have this tcp socket chat application from youtube

server side

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();

}

client side

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); 
    }
}

now, all of these works fine for me, however everytime i close one them i get this error 'Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.' at ClientReceive() or ServerReceive()

how should i catch this error if one of them suddenly closed or the network cable suddenly unplug? thanks in advance

1
With a try..catch block.CodeCaster

1 Answers

0
votes

In this case, you're receiving a System.IO.IOException from the NetworkStream object. This exception has a nested System.Net.Sockets.SocketException with an ErrorCode of 10054 (SocketErrorCode == ConnectionReset). To handle the exception, use a try-catch block. For example,

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();