Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.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'读取所有可用数据;s async_read_some()而不等待新数据到达?_C++_Boost_Serial Port_Boost Asio - Fatal编程技术网

C++ 如何使用boost::asio'读取所有可用数据;s async_read_some()而不等待新数据到达?

C++ 如何使用boost::asio'读取所有可用数据;s async_read_some()而不等待新数据到达?,c++,boost,serial-port,boost-asio,C++,Boost,Serial Port,Boost Asio,我正在使用boost::asio进行串行通信,并且我希望侦听某个端口上的传入数据。因此,我使用serialport::async\u read\u some()注册一个ReadHandler,然后创建一个单独的线程来处理异步处理程序(调用io\u service::run())。我的ReadHandler通过再次调用async\u read\u some()在末尾重新注册自己,这似乎是一种常见的模式 这一切都是可行的,我的示例可以在接收数据时将数据打印到stdout中,只是我注意到在ReadHa

我正在使用boost::asio进行串行通信,并且我希望侦听某个端口上的传入数据。因此,我使用
serialport::async\u read\u some()
注册一个ReadHandler,然后创建一个单独的线程来处理异步处理程序(调用
io\u service::run()
)。我的ReadHandler通过再次调用
async\u read\u some()
在末尾重新注册自己,这似乎是一种常见的模式

这一切都是可行的,我的示例可以在接收数据时将数据打印到stdout中,只是我注意到在ReadHandler运行时接收到的数据不会被“读取”,直到ReadHandler执行完毕并在执行之后接收到新数据。也就是说,当ReadHandler运行时收到数据时,尽管在ReadHandler结束时调用了async_read_some,但它不会立即再次为该数据调用ReadHandler。只有在初始ReadHandler完成后收到其他数据时,才会再次调用ReadHandler。此时,ReadHandler运行时接收的数据将与“新”数据一起正确地位于缓冲区中

这是我的最低可行的例子——我最初把它放在Wandbox中,但意识到它对在线编译没有帮助,因为它需要一个串行端口才能运行

//包括标准库
#包括
#包括
#包括
#包括
//包括ASIO网络库
#包括
类串行端口
{
公众:
显式串行端口(const std::string和portName):
m_startTime(std::chrono::system_clock::now()),
m_readBuf(新字符[bufSize]),
m_ios(),
m_ser(m_ios)
{
m_ser.open(端口名称);
m_ser.set_选项(boost::asio::串行_port_base::波特率(115200));
auto readHandler=[&](常量boost::system::error\u code&ec,std::size\u t bytesRead)->void
{
//需要将lambda作为输入参数传递,而不是捕获,因为我们使用的是自动存储类
//所以使用这里提到的技巧:http://pedromelendez.com/blog/2015/07/16/recursive-lambdas-in-c14/
//在这里:https://stackoverflow.com/a/40873505
auto readHandlerImpl=[&](常量boost::system::error\u code&ec,std::size\u t bytesRead,auto&lambda)->void
{
如果(!ec)
{
const auto-appeased=std::chrono::duration\u cast(std::chrono::system\u clock::now()-m\u startTime);

std::cout回答标题中的问题:你不能。根据
异步读取某些
的性质,你要求进行部分读取,并在读取任何内容后立即调用处理程序。然后在调用另一个
异步读取某些
之前,你会睡很长时间

无论我以多快的速度创建ReadHandler,它仍然有可能“丢失”数据(在以后接收到一些新数据之前,它不会被看到)

如果我正确理解了您的担忧,那没关系——您不会错过任何东西。数据仍然在套接字/端口缓冲区中等待,直到下次您读取它


如果您只想在读取完成后开始处理,则需要一个重载。这实际上会在流上执行多个读取,直到满足某些条件。这可能意味着端口/套接字上的所有内容,或者您可以提供一些自定义的
CompletionCondition
。在每次读取时都会调用此函数直到它返回0,此时读取被视为完成,然后调用
ReadHandler

谢谢!我担心的是,即使我没有遗漏任何内容,在之后收到更多数据之前,我也不会知道数据已被接收。我尝试将
async\u read
boost::asio::transfer\u一起使用,至少(1)
作为我的CompletionCondition,但行为是一样的。我在“这里有一个更清晰的描述…”下对我的问题进行了澄清。这有意义吗?我想你是对的-似乎没有任何方法可以实现我对async\u read\u some的要求。也许他们设计中的想法是大多数人都在寻找完整的mes一些协议中的贤哲,所以他们可以像你说的那样使用async_。但是我仍然不明白有人会如何实现一个基本的串行控制台(la RealTerm),在这种情况下,您不知道有多少数据正在到来或以何种形式出现,您需要在收到数据后立即将所有数据显示在屏幕上。感谢您花时间回答!您的问题基本上没有意义。您将收到第一个读取处理程序中已经到达的所有数据,并且您将无法再收到任何数据直到该处理程序退出并调用下一个处理程序。如果速度较慢,则加快速度。我认为我在标题中的措辞不正确,但我担心的是,在收到新数据之前,调用的下一个处理程序不会调用我的ReadHandler,而不是在执行第一个ReadHandler期间操作系统接收到的任何数据。这不是数据丢失了,但在以后接收到更多数据之前,我不知道收到了数据。也就是说,在接收到新数据之前,我无法访问临时数据。这有意义吗?