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();
}
}
- 对于50%的TCP问题,您没有使用从网络读取的返回值。TCP是基于流的,不是基于消息的。
- ReceiveBufferSize不是你想的那样。查看文档。
- 你的资源管理在错误的情况下可能会导致你的问题,因为你不清理。
- 不要使用ASCII编码。如果没有很好的理由做其他事情,请使用UTF8。
- 不要依赖
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();
}
}