小弟不才,不是学软件出身,所以做上位机软件也是头一次,CSDN上也看到了很多关于线程之类的处理,确实不太明白。
这次单位要求用RS232通信,并接收数据后处理结果。
RS232收到上位机发送的START信号后,首先快速的返回"Ver=XX",然后隔个5秒或6秒(肯定10秒以内)后返回结果"CODE=XX",XX的不同代表了不同的返回结果,所以需要针对XX做进一步的处理(函数Display())。
但是由于两组数据之间间隔时间较长,DataReceived又是按字节触发,有时会认为第一组数据接收到后就结束,或者收到部分数据,然后就去执行Display()函数了,导致最终的结果肯定不对。我怎么保证我能每次都能收到完整的数据?
谢谢!
这次单位要求用RS232通信,并接收数据后处理结果。
RS232收到上位机发送的START信号后,首先快速的返回"Ver=XX",然后隔个5秒或6秒(肯定10秒以内)后返回结果"CODE=XX",XX的不同代表了不同的返回结果,所以需要针对XX做进一步的处理(函数Display())。
但是由于两组数据之间间隔时间较长,DataReceived又是按字节触发,有时会认为第一组数据接收到后就结束,或者收到部分数据,然后就去执行Display()函数了,导致最终的结果肯定不对。我怎么保证我能每次都能收到完整的数据?
谢谢!
解决方案 »
- 在gridview中选中某行点击超链接显示这行的详细信息怎么实现?
- 如何用正则表达式查找信息
- 我有个.lib和.h文件,是C的,请问怎么生成DLL文件?
- 刚搞懂了生成静态,遇到棘手问题(十万火急)
- 怎么计算ListSubItem中的字符长度?
- 局域网内知道IP可以知道其MAC地址吗?
- 初学乍练:不能加载用户控件?
- 请教~~~~~~~~~~
- 请问为什么我用 regasm.exe 不能正确注册C#组件,而在.net开发环境下选中Register for Com interop就可以呢?
- 急,急,那位用C# 做过按照指定数据包格式协议,发送报文的程序。可否给与指教。马上给分
- 求教方案:使用WebBrowser打印网页小票,需要指定打印机
- HTTP Error 500.0 - Internal Server Error 您查找的资源存在问题,因而无法显示。
这就是编程设计问题。DataReceived 事件触发之后,你收到的字节本来就应该跟以前收到的内容一起、累积到一个集合中,例如一个 List<byte> 集合中。然后判断有没有一条完整的消息。如果有,就从中取出第一条消息,进行解析处理。如果没有就什么也不用做了。
数据接收后根据规约判定报文是否完整,
1.长度不够---->继续接收;
2.长度恰好是一个完整的包 ----> 完成解析;
3.长度不止一个包,循环解析;
这就是编程设计问题。DataReceived 事件触发之后,你收到的字节本来就应该跟以前收到的内容一起、累积到一个集合中,例如一个 List<byte> 集合中。然后判断有没有一条完整的消息。如果有,就从中取出第一条消息,进行解析处理。如果没有就什么也不用做了。我主要疑问在Display()函数应该放哪里?Send_Ins(); //发送函数//===============
//数据处理
// if (txtBoxS1.Text.Length == 50)
// {
// Display();
// }
// else
// TestResult1_FailLength();
//===============private List<byte> buffer1 = new List<byte>(4096);
private void S1Com_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int count=0;
if (S1Com.IsOpen)
{
try
{
do
{
count = S1Com.BytesToRead;
if (count <= 0)
break;
Byte[] receivedData = new byte[count];
S1Com.Read(receivedData, 0, count);
buffer1.AddRange(receivedData);
foreach (byte b in receivedData)
{
txtBoxS1.Text += Convert.ToChar(b);
} } while (S1Com.BytesToRead > 0);
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message, "出错提示");
txtBoxS1.Text = "";
}
//数据处理
if (txtBoxS1.Text.Length == 50)
{
Display();
}
else
TestResult1_FailLength();
}
}由于一开始数据肯定不会满50个字符,程序一直会走到 TestResult1_FailLength()函数里面。
如果我把数据处理那段if...else..,放到Send_Ins();函数后面,也不会等S1Com_DataReceived()处理完才做,所以不知所措。麻烦请指导。
如果一个包中间TimeOut呢?
byte[] byteBuffer = Encoding.ASCII.GetBytes(strSendIns);S1Com.Write(byteBuffer, 0, byteBuffer.Length);而串口设置如下:S1Com.PortName = cbSerial1.Text;
S1Com.BaudRate = Convert.ToInt32(BaudRate);
S1Com.DataBits = Convert.ToInt32(DataBits);
S1Com.StopBits = StopBits.One;
S1Com.Parity = Parity.None;我不明白你指的报文起始符,结束符,校验符是什么?串口默认是从低电平作为start bit。
在你的receive函数中,
1.接收到的数据增加到list中,
2.然后调用display,判断是否接收完整,如果完整接收到,解释数据,并将解释完的数据从list中删除。如果没有接收到完整的数据,返回。接收到非法数据,删除非法数据;
如果一个包中间TimeOut呢?如果timeout,
接收侧直接断开连接即可
让client重新发起连接,重新发送数据
如果一个包中间TimeOut呢?如果timeout,
接收侧直接断开连接即可
让client重新发起连接,重新发送数据
“接收方直接断开连接”是指断开串口嘛?