TcpClient在一次读写数据后冻结

本文关键字:读写 数据 冻结 一次 TcpClient | 更新日期: 2023-09-27 18:02:36

我有个问题想不出来。我有一个简单的服务器写在python上运行的树莓派。服务器只是用反向字符串回答。我用c#编写的客户端程序与我的PC连接在一起。我可以连接到我的服务器,发送字符串给它,并从它得到答案,但只是第一次,我的程序完全冻结。我得到IO异常,如果我试图发送数据不止一次:

IO异常WRITE at System.Net.Sockets.NetworkStream。写入(Byte[] buffer, Int32偏移量,Int32大小)在System.IO.StreamWriter。Flush(Boolean flushStream, Boolean flushEncoder)在System.IO.StreamWriter.Flush ()类型'System.IO '的第一次机会异常。

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

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

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

我相信这是我的程序出了问题,因为如果我在我的PC上运行用python编写的客户端程序,它会持续工作,而不仅仅是一次。

但有趣的是,同样的客户端代码与一些使用TCP/IP进行通信的工业设备完美地工作。

下面是我的代码:

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

TcpClient在一次读写数据后冻结

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

更新代码:

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