【问题标题】:Receiving messages part by part from serial port using c#使用c#从串口部分接收消息
【发布时间】:2010-04-09 03:25:25
【问题描述】:

我正在使用以下代码使用 c# 从串口接收消息

    void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        if (comPort.IsOpen == true)
        {
            string msg = comPort.ReadExisting();
            MessageBox.Show(msg.Trim());
        }
    }

问题是,我正在逐步收到消息。比如,如果你发送“你好,你好吗” 我一个字一个字地收到。我想一口气做到这一点。我该怎么办??

另外,是否可以检索应用程序发送和接收消息的端口名称?

【问题讨论】:

标签: c# serial-port


【解决方案1】:

到目前为止,通过串行端口一次性传输固定数量的数据的最简单方法是在数据前面加上长度标头。使用固定数量的字节作为长度(2-4 应该足够了),然后使用Read 方法同步读取length 字节的数据。当然,你也可以异步执行此操作,只需将长度保存在某个成员字段中,并在达到长度后立即执行后处理。

下一个最好的方法是附加一个停止字符或单词。如果它恰好是换行符,那么您可以使用同步 SerialPort.ReadLine 方法。否则,将接收到的数据收集到 StringBuilder 中,继续附加到 StringBuilder 直到您点击停止字符,然后返回该 StringBuilder 的内容直到(但不包括)停止字符。

如果你对源数据没有控制权,需要读取固定数量的数据,并且事先不知道那个大小是多少,那么你的工作将是相当艰巨的更加困难。我认为真正处理这种情况的唯一方法是等待预定的超时,此时如果您没有收到任何新数据,则假设传输结束。它不是特别可靠,这就是为什么大多数通信协议都使用上述设计之一的原因。

如果您考虑串行端口(或任何端口)的工作方式,只需将位推过电线,那么应该清楚的是,如果无法预测,就无法知道传输是否完成未来。如果您连接到远程主机(即通过调制解调器),并且该主机在传输完成后断开您的连接,那么您可能可以使用载波检测,但这听起来不像这里的情况。

希望这不是您当前所处的场景,或者您具有控制源数据的能力,或者您正在连接的设备已经使用了长度标头和/或停止模式。如果是这样,一定要使用它。否则,您可能会因超时而陷入困境。

【讨论】:

    【解决方案2】:
       private void MonitorSP_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                try
                {
                    System.IO.Ports.SerialPort SP = (System.IO.Ports.SerialPort)sender;
    
                    //Get the ports available in system
                    string[] theSerialPortNames = System.IO.Ports.SerialPort.GetPortNames();
                    string strAvlPortNames = "";
                    foreach (string s in theSerialPortNames)
                    {
                        strAvlPortNames += s.ToString() + ", ";
                    }
    
                    //Read an contruct the message
                    Thread.Sleep(1000);
                    string msg = SP.ReadExisting();
                    string ConstructedMsg = "Port's Found : " + strAvlPortNames + "\n" + "Port Used : " + SP.PortName + "\n" + "Message Received : " + msg;
    
                    if (InvokeRequired)
                    {
                        richTextBox1.Invoke(new MethodInvoker(delegate { richTextBox1.Text = ConstructedMsg; }));
                        //Send acknowlegement to sender port
                        SP.Write(SP.PortName);
                        return;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.StackTrace.ToString());
                }
            }  
    

    【讨论】:

      【解决方案3】:

      尝试阅读,直到找到CRLF

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-02
        • 1970-01-01
        • 2017-05-29
        相关资源
        最近更新 更多