Получение сообщений по частям из последовательного порта с использованием c # - PullRequest
1 голос
/ 09 апреля 2010

Я использую приведенный ниже код для получения сообщений от последовательного порта с помощью c #

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

Проблема в том, что я получаю сообщения по частям. Как, если вы отправляете "Привет, как дела" Я получаю это слово за словом. Я хочу это одним махом. Как я могу сделать ??

Также возможно ли получить имя порта, с которого приложение отправляет и получает сообщения?

Ответы [ 3 ]

3 голосов
/ 09 апреля 2010

Безусловно, самый простой способ передачи фиксированного количества данных через последовательный порт за один прием - это предварительно добавить данные с заголовком длины. Используйте фиксированное количество байтов для длины (должно хватить 2-4), а затем считывайте length байтов данных синхронно, используя метод Read. Вы также можете делать это асинхронно, конечно, вам просто нужно сохранить длину где-нибудь в поле члена и выполнить постобработку, как только длина будет достигнута.

Следующий лучший способ - добавить символ остановки или слово. Если это новая строка, вы можете использовать синхронный метод SerialPort.ReadLine . В противном случае, соберите полученные данные в StringBuilder, продолжайте добавлять к StringBuilder до тех пор, пока вы не нажмете символ остановки, затем верните содержимое этого StringBuilder до (но исключая) символа остановки.

Если у вас нет контроля над исходными данными, вам нужно прочитать фиксированный объем данных, и не знают заранее, что это за размер, тогда ваша работа будет значительно больше сложно. Я думаю, что единственный способ по-настоящему справиться с этой ситуацией - это подождать заранее определенный тайм-аут, после чего вы предполагаете, что передача закончена, если вы не получили никаких новых данных. Это не особенно надежно, поэтому большинство протоколов связи используют один из вышеупомянутых проектов.

Если вы думаете о том, как работает последовательный порт (или любой другой порт), просто проталкивая биты по проводам, тогда должно быть ясно, что нет способа узнать, завершена ли передача, не имея возможности предсказать будущее. Если вы подключены к удаленному хосту, то есть через модем, и этот хост отключает вас, когда передача завершена, вы можете использовать функцию обнаружения несущей, но это не похоже на случай.

Надеюсь, это не тот сценарий, в котором вы сейчас находитесь, и у вас есть возможность управлять исходными данными, или устройство, к которому вы подключаетесь, уже использует заголовок длины и / или шаблон остановки. Если это так, обязательно используйте это. В противном случае вы, вероятно, застрянете, используя таймауты.

1 голос
/ 18 мая 2010
   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());
            }
        }  
0 голосов
/ 09 апреля 2010

Попробуйте читать, пока не нажмете CRLF.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...