[英]C# - SerialPort Receive Doesn't Get All the Data at Once
对于串行端口,我有一个奇怪的难题。 我正在向具有微控制器的设备发送一堆命令,并获得响应。 很典型的东西。 无论如何,我遇到一个问题,当我发送命令时,DataReceived事件处理程序确实会响应,但是问题是我没有从中获取所有数据。 结果,DataReceived事件处理程序最终被调用了4次。
因此,而不是得到这样的东西:
0 - 2:16:38 PM: 126 23 100 69 0 0 99 3 225 2 203 2 174 2 179 2 125 93 3 15 3
0 0 0 15 255 0 214 12 105 15 33 15 33 15 13 15 54 15 39 5 68 4 197 5 199 5 57
5 0 0 0 134 225
1 - 2:16:38 PM: 126 23 100 69 0 0 99 3 226 2 203 2 174 2 179 2 125 93 3 16 3
0 0 0 15 255 0 224 12 105 15 23 15 33 15 2 15 74 15 39 5 58 4 197 5 198 5 57
5 0 0 0 65 163
2 - 2:16:38 PM: 126 23 100 69 0 0 99 3 226 2 202 2 174 2 178 2 125 93 3 15 3
0 0 0 15 255 0 214 12 95 15 23 15 33 15 23 15 105 15 39 5 58 4 197 5 198 5 57
5 0 0 0 63 128
代码最终如下所示(不精确,但给出了一个示例):
0 - 2:16:38 PM: 126 23 100 69 0 0 99 3 225 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 - 2:16:38 PM: 2 203 2 174 2 179 2 125 93 3 15 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 - 2:16:38 PM: 15 255 0 214 12 105 15 33 15 33 15 13 15 54 0 0 0 0 0 0 0 0 0
0 - 2:16:38 PM: 15 39 5 68 4 197 5 199 5 57 5 0 0 0 134 225 0 0 0 0 0 0 0 0 0
第一条数据线接受4个事件调用而不是1个事件调用,我假设微控制器仍在发送数据,因为我一次发送所有写数据。 但是我希望有一种控制它的方法,这样我就不会收到所有这些事件调用(因为我更喜欢将字节数组放在一个数组而不是块中)。
这一切都由Visual Studio 2010进行编程,但是如果需要的话,我可以尝试2013。 这是我用来获得与上述结果相似的示例代码(我知道文件流编写器在使用该代码时不会关闭,但是我仅以主要代码为例):
namespace SerialCommunicationsTest
{
class Program
{
static UInt64 count = 0;
static SerialPort port;
static System.IO.StreamWriter file;
static void Main(string[] args)
{
file = new System.IO.StreamWriter(@"C:\Users\li\Desktop\Serial.txt");
port = new SerialPort("COM6", 9600, Parity.None, 8, StopBits.One);
port.Handshake = Handshake.None;
port.Open();
port.ReadTimeout = 400;
port.WriteTimeout = 400;
byte[] output = { 0x7E, 0x64, 0x17, 0x01, 0x45, 0x40, 0xFA, 0x7E };
port.DataReceived += new SerialDataReceivedEventHandler(SerialPortDataReceived);
/* Loop, send message, and have event handler handler handle incoming event */
while (count < UInt64.MaxValue)
{
port.Write(output, 0, output.Length);
}
return;
}
static void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort port = (SerialPort)sender;
byte[] test = new byte[256];
try
{
string data2 = "";
port.Read(test, 0, 256);
for (int i = 0; i < 60; i++)
{
data2 += test[i] + " ";
}
string writeOut = count + " - " + DateTime.Now.ToString("h:mm:ss tt") + ": " + data2;
Console.WriteLine(writeOut);
file.WriteLine(writeOut);
count++;
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
}
}
}
如果您知道多个消息的固定长度,可以重复调用Read
直到您读完所有字节以填充一个byte[]
然后将该数组传递给另一个,这是您的责任:将多个读取调用组合成一个“消息”职能。
const int MessageSize = 256;
byte[] test = new byte[MessageSize];
int offset = 0;
static void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort port = (SerialPort)sender;
try
{
offset += port.Read(test, offset, MessageSize - offset);
if(offset == MessageSize)
{
string data2 = "";
for (int i = 0; i < 60; i++)
{
data2 += test[i] + " ";
}
string writeOut = count + " - " + DateTime.Now.ToString("h:mm:ss tt") + ": " + data2;
Console.WriteLine(writeOut);
file.WriteLine(writeOut);
count++;
offset = 0;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
}
尝试这个:
List<byte> dataBuffer = new List<byte>();
byte[] tempBuff;
var bytesReaded = pt.Read(inBuff, 0, inBuffSize);
while (bytesReaded > 0)
{
tempBuff = new byte[bytesReaded];
Array.Copy(inBuff, tempBuff, bytesReaded);
dataBuffer.AddRange(tempBuff);
bytesReaded = pt.Read(inBuff, 0, inBuffSize);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.