一次写入后TcpClient冻结并读取数据C#

时间:2014-05-10 11:28:14

标签: c# .net tcpclient

我有问题,我无法弄明白。我有用Python编写的简单服务器,它运行在Raspberry Pi上。服务器只是用反向字符串回答。我正在使用C#编写的客户端程序与我的PC连接。我可以连接到我的服务器,发送字符串并从中获得答案,但仅仅是第一次,我的程序完全冻结。如果我尝试多次发送数据,我会得到IO异常:

System.Net.Sockets.NetworkStream.Write上的IO异常WRITE(Byte []缓冲区,Int32偏移量,Int32大小)    在System.IO.StreamWriter.Flush(Boolean flushStream,Boolean flushEncoder)    在System.IO.StreamWriter.Flush() System.dll

中出现'System.IO.IOException'类型的第一次机会异常

有时在程序冻结之前,在调用ReadData之后我得到下一个异常:

无法从传输连接中读取数据:已建立的连接已被主机中的软件中止。

我读到了可能由Windows防火墙或反病毒程序引起的异常。我把它关掉了,但仍然是一样的。我还在我的服务器上设置了静态IP,并将其直接连接到我的PC,但仍然是相同的。

我认为我的程序出了问题,因为如果我在用python编写的PC上运行Client程序,它会连续工作,而不仅仅是一次。

但有趣的是,相同的客户端代码与某些使用TCP / IP进行通信的工业设备完美配合。

这是我的代码:

公共部分类Form1:表单     {

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

2 个答案:

答案 0 :(得分:1)

  1. 与50%的TCP问题一样,您没有使用网络读取的返回值。 TCP是基于流的,而不是基于消息的。
  2. ReceiveBufferSize不是你想象的那样。查看文档。
  3. 如果出现错误,您的资源管理可能会导致您的问题,因为您无法清理。
  4. 不要使用ASCII编码。如果没有充分理由做其他事情,请使用UTF8。
  5. 不要依赖Connected。如果连接断开,您将收到异常。 Connected总是过时的。

答案 1 :(得分:0)

更新的代码:

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