anze87
anze87

Reputation: 253

TcpClient freezes after one write and read data C#

I have problem that I can't figure it out. I have simple server written in python that runs on Raspberry Pi. Server just answers with reversed string. I am connecting on it with my PC with client program written in C#. I can connect to my server, send string to it and get answer from it, but just for the FIRST time, than my program totally freezes. I get IO exception, if I am trying to send data more than once:

IO exception WRITE at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size) at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder) at System.IO.StreamWriter.Flush() A first chance exception of type 'System.IO.IOException' occurred in System.dll

Sometimes before program freezes, after calling ReadData I get next exception:

Unable to read data from the transport connection: An established connection was aborted by the software in your host machine.

I read about that exception that may be caused of windows firewall or anti virus program. I turned it off both of it and still the same. I also set static IP on my server and connect it direct in my PC but still the same.

I believe that is something wrong with my program, because if I run Client program on my PC written in python, it works continiously, not just once.

But intersting thing is, that same client code works perfectly with some industrial device, which uses TCP/IP for communication.

Here's my code:

public partial class Form1 : Form {

    string ipAdress = "192.168.1.74";

    int port = 9997;

    TcpClient tcpIpClient = new TcpClient();
    NetworkStream netStream = null;

    StreamWriter streamWriter;


    public Form1()
    {
        InitializeComponent();            
    }

    private string GetCheckSum(string data)
    {
        int checksum = 0;
        for (int i = 0; i < data.Length; i++)
        {
            checksum ^= Convert.ToByte(data[i]);
        }
        return checksum.ToString("X2");
    }

    private void CreateConnection()
    {
        try
        {
            tcpIpClient.Connect(ipAdress, port);

            netStream = tcpIpClient.GetStream();

            streamWriter = new StreamWriter(netStream);

            if (tcpIpClient.Connected)
            {
                pictureBox1.Image = Image.FromFile(@"Resources\Aqua-Ball-Green-icon.png");
                Console.Write("Connected");

            }
            else
                MessageBox.Show("Restart");

        }
        catch (Exception excep)
        {
            Console.WriteLine("Error.. " + excep.StackTrace);
        }
    }

    private void SendData(string command)
    {
        try
        {
            streamWriter.Write("$" + command + GetCheckSum(command) + "0");
            streamWriter.Flush();
        }
        catch (Exception excep)
        {
            Console.WriteLine("IO exception WRITE" + excep.StackTrace);
        }
    }

    private void ReadData()
    {
        string returnedData = null;
        //receiving server response 
        byte[] bytes = new byte[tcpIpClient.ReceiveBufferSize];
        int bytesread = tcpIpClient.ReceiveBufferSize;
        if (netStream.CanRead)
        {
            netStream.Read(bytes, 0, bytesread);                   
            //received response, now encoding it to a string from a byte array
            returnedData = Encoding.ASCII.GetString(bytes);
            Console.WriteLine("Data read..." + returnedData);
            //Console.WriteLine(returnedData);
        }
        else
        {
            Console.WriteLine("You cannot read data from this stream.");
            tcpIpClient.Close();

            // Closing the tcpClient instance does not close the network stream.
            netStream.Close();
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        CreateConnection();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        ReadData();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        SendData();
    }
}

Upvotes: 0

Views: 2691

Answers (2)

anze87
anze87

Reputation: 253

Updated code:

public partial class Form1 : Form
{

    string ipAdress = "192.168.1.74";

    int port = 9997;

    TcpClient tcpClient = new TcpClient();
    NetworkStream networkStream = null;

    StreamWriter streamWriter;


    public Form1()
    {
        InitializeComponent();            
    }

    private string GetCheckSum(string data)
    {
        int checksum = 0;
        for (int i = 0; i < data.Length; i++)
        {
            checksum ^= Convert.ToByte(data[i]);
        }
        return checksum.ToString("X2");
    }

    private void CreateConnection()
    {
        try
        {
            tcpClient.Connect(ipAdress, port);

            networkStream = tcpClient.GetStream();

            streamWriter = new StreamWriter(networkStream);

            if (tcpClient.Connected)
            {
                pictureBox1.Image = Image.FromFile(@"Resources\Aqua-Ball-Green-icon.png");
                Console.Write("Connected");

            }
            else
                MessageBox.Show("Restart");

        }
        catch (Exception excep)
        {
            Console.WriteLine("Error.. " + excep.StackTrace);
        }
    }

    private void ReadData()
    {
        //receiving server response 
        byte[] bytes = new byte[1024];

        if (networkStream.CanRead)
        {
            int bytesRead = networkStream.Read(bytes, 0, bytes.Length);                   
            //received response, now encoding it to a string from a byte array
            Console.WriteLine("odgovor" + Encoding.UTF8.GetString(bytes, 0, bytesRead));
        }
        else
        {
            Console.WriteLine("You cannot read data from this stream.");
            tcpClient.Close();

            // Closing the tcpClient instance does not close the network stream.
            networkStream.Close();
        }
    }

    private void SendData(string command)
    {
        if (networkStream.CanWrite)
        {

            // Does a simple write.
            Byte[] sendBytes = Encoding.UTF8.GetBytes("Is anybody there");
            networkStream.Write(sendBytes, 0, sendBytes.Length);;
        }
        else if (!networkStream.CanWrite)
        {
            Console.WriteLine("You can not read data from this stream");
            tcpClient.Close();
        }
    }
    private void button5_Click(object sender, EventArgs e)
    {
        CreateConnection();
    }

    private void button7_Click(object sender, EventArgs e)
    {
        ReadData();
    }

    private void button6_Click(object sender, EventArgs e)
    {
        SendData();
    }
}

Upvotes: 0

usr
usr

Reputation: 171168

  1. As with 50% of the TCP questions, you are not using the return value of reads from the network. TCP is stream-based, not message based.
  2. ReceiveBufferSize is not what you think it is. Look into the docs.
  3. Your resource management in case of error might contribute to your problem because you don't clean up.
  4. Don't use ASCII encoding. Use UTF8 if there is no very good reason to do something else.
  5. Don't rely on Connected. You'll get an exception if the connection drops. Connected is always out of date.

Upvotes: 1

Related Questions