Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用Boost Asio从串行端口读取数据_C++_Serial Port_Boost Asio_Streambuf - Fatal编程技术网

C++ 使用Boost Asio从串行端口读取数据

C++ 使用Boost Asio从串行端口读取数据,c++,serial-port,boost-asio,streambuf,C++,Serial Port,Boost Asio,Streambuf,我想使用boost.asio检查串行端口上的传入数据包。每个数据包将以一个字节长的报头开始,并将指定已发送的消息类型。每种不同类型的消息都有自己的长度。我想要编写的函数应该不断地侦听新传入的消息,当它找到一条消息时,应该读取它,并调用其他函数来解析它。我目前的代码如下: void check_for_incoming_messages() { boost::asio::streambuf response; boost::system::error_code error;

我想使用
boost.asio
检查串行端口上的传入数据包。每个数据包将以一个字节长的报头开始,并将指定已发送的消息类型。每种不同类型的消息都有自己的长度。我想要编写的函数应该不断地侦听新传入的消息,当它找到一条消息时,应该读取它,并调用其他函数来解析它。我目前的代码如下:

void check_for_incoming_messages()
{
    boost::asio::streambuf response;
    boost::system::error_code error;
    std::string s1, s2;
    if (boost::asio::read(port, response, boost::asio::transfer_at_least(0), error)) {
        s1 = streambuf_to_string(response);
        int msg_code = s1[0];
        if (msg_code < 0 || msg_code >= NUM_MESSAGES) {
            // Handle error, invalid message header
        }
        if (boost::asio::read(port, response, boost::asio::transfer_at_least(message_lengths[msg_code]-s1.length()), error)) {
            s2 = streambuf_to_string(response);
            // Handle the content of s1 and s2
        }
        else if (error != boost::asio::error::eof) {
            throw boost::system::system_error(error);
        }
    }
    else if (error != boost::asio::error::eof) {
        throw boost::system::system_error(error);
    }
}
void check\u查看\u传入的\u消息()
{
boost::asio::streambuf响应;
boost::system::error\u code error;
std::字符串s1,s2;
if(boost::asio::read(端口、响应、boost::asio::transfer_至少(0),错误)){
s1=streambuf_至_字符串(响应);
int msg_code=s1[0];
如果(消息代码<0 | |消息代码>=NUM_消息){
//句柄错误,消息头无效
}
if(boost::asio::read(端口、响应、boost::asio::transfer_至少(消息长度[msg_code]-s1.length()),错误)){
s2=流BUF_到_字符串(响应);
//处理s1和s2的内容
}
else if(error!=boost::asio::error::eof){
抛出boost::system::system\u错误(error);
}
}
else if(error!=boost::asio::error::eof){
抛出boost::system::system\u错误(error);
}
}
boost::asio::streambuf
是正确的工具吗?我如何从中提取数据以便分析消息?我还想知道我是否需要一个单独的线程,它只调用这个函数,这样就可以更频繁地调用它。我是否应该担心由于高流量和串行端口缓冲区耗尽而在两次函数调用之间丢失数据?我正在使用Qt的GUI库,我真的不知道处理所有事件需要多少时间


编辑:有趣的问题是:如何检查串行端口是否有任何传入数据?如果没有传入数据,我不希望函数阻止…

本文有助于理解ASIO如何与串行端口异步使用:

更新(2019-03):

我链接到的原始文章已不再可用,即使在互联网档案中也很难找到。(这是一个。)。现在有一些关于使用ASIO进行串行I/O的较新文章可以通过搜索轻松找到,但这篇较旧的文章仍然非常有用。我把它放在一个公共要点中,这样它就不会丢失:

文章中描述的代码似乎是复制到这里的:

作者似乎已经为C++11更新了它。我相信这篇文章是正确的 原著作者。

Jason

如果它适合您的应用程序,我强烈建议实现基于回调的异步串行接收。有一个关于如何实现带超时的异步串行的很好的小例子。正如您所认识到的,它需要多线程实现才能获得性能优势,因此您需要考虑将接收到的数据缓冲到哪里,以确保不会进行大量复制

至于
boost::streambuff
这类东西,我个人更喜欢将一些内存作为一个字符数组来屏蔽-
charm\u RXBuffer[m\u RXBuffSize]
并使用
boost::asio::buffer(m\u RXBuffer,m\u RXBuffSize)
将目标缓冲区传递到
异步读取部分
。特别是对于RS232,我总是发现这样一个事实:底层数据是一个字节流,自然地映射到一个简单的字符数组上要比映射到任何更复杂的数据结构好得多


祝你好运

谢谢!:)我发现我也必须这样做,我发现我必须异步读取,以避免中断程序流。以前,我使用的是
read
函数,而
async\u read
是正确的函数。写入也是一样,
async\u write
应用于防止程序在由于某种原因导致读取暂停时冻结程序。@hellogoodbay您能与我分享fede网页上的源代码吗?该站点现在正在移动到Internet存档,无法再进行克隆。谢谢大家!@ShawnLe我希望原始资料将很快可以在互联网档案中进行克隆。但是,原始文章的来源似乎也可以在Github上找到: