C++ boost::asio::重新连接设备后的串行_端口读数

C++ boost::asio::重新连接设备后的串行_端口读数,c++,boost,serial-port,boost-asio,C++,Boost,Serial Port,Boost Asio,我在从GPS设备(USB串行)读取boost::asio::serial_port类时遇到问题。连接设备并从中读取工作正常,但当我断开并重新连接设备时,read_some不会从端口读取任何字节 由于boost无法检测串行端口是否消失(is_open()返回true),因此我会定期取消()、关闭()并在未获取数据时打开(GPS_port)设备,同时重置端口选项。但这也没有帮助,输入缓冲区保持为空 我是否遗漏了什么,或者做错了什么,或者这是asio中的一个bug?是否有一种标准的方法来检测端口是否消

我在从GPS设备(USB串行)读取boost::asio::serial_port类时遇到问题。连接设备并从中读取工作正常,但当我断开并重新连接设备时,read_some不会从端口读取任何字节

由于boost无法检测串行端口是否消失(is_open()返回true),因此我会定期取消()、关闭()并在未获取数据时打开(GPS_port)设备,同时重置端口选项。但这也没有帮助,输入缓冲区保持为空


我是否遗漏了什么,或者做错了什么,或者这是asio中的一个bug?是否有一种标准的方法来检测端口是否消失?

很难说具体原因是什么,但实践表明,您经常需要禁用串行端口上的
RTS
灵敏度

RTS
是real
RS-232
接口上的pin,当另一侧的设备打开时,该接口处于打开状态

serial\u port::read\u some
调用查看此信号的底层
Windows API
函数

由于您没有真正的
RS-323
设备,因此需要依赖此信号的驱动程序模拟,这可能会出现故障(不幸的是,通常会出现故障)

要禁用它,请使用
rtscoontrol
设置为
RTS\u CONTROL\u disable
调用
serial\u port::set\u option(DCB)

如果
close()
“按下手柄不起作用,则可能是
boost
有问题。
close()
的源代码如下所示:

  boost::system::error_code close(implementation_type& impl,
      boost::system::error_code& ec)
  {
    if (is_open(impl))
    {
      if (!::CloseHandle(impl.handle_))
      {
        DWORD last_error = ::GetLastError();
        ec = boost::system::error_code(last_error,
            boost::asio::error::get_system_category());
        return ec;
      }

      impl.handle_ = INVALID_HANDLE_VALUE;
      impl.safe_cancellation_thread_id_ = 0;
    }

    ec = boost::system::error_code();
    return ec;
  }
,i。E如果
CloseHandle()
由于某种原因失败(或挂起),则内部句柄值不会分配给
无效的句柄值
,并且
处于打开状态()
将始终返回
真值


要解决此问题,请在
close()
'ing之后立即检查
is\u open()
,如果返回
true
,销毁整个
boost::asio::serial\u端口实例,然后重新创建它。

通常,当
read\u some
无法再准备时,您会得到类型为
boost::system::system\u error
的异常。尝试使用
read
,它可能会返回一个错误,而不仅仅是返回。您也可以尝试异步方法;在这种情况下,当设备断开连接时,处理程序应该得到一个错误对象


或者,您可以使用
native()
函数获取端口的句柄,并对其调用ClearCommError()。它可能会返回错误。

尽管asio
boost::ip:tcp
易于处理,但我认为在Windows 7上处理boost
串行端口需要特别小心。
我遇到了类似的问题,通过重置
boost::asio::io_service
io_service.reset()

我可以异步读取数据,但在第二次尝试时无法执行相同的操作。
实际上,读取函数本身没有问题,注册异步读取失败,这导致在第二次尝试时立即从
boost::asio::io\u service::run()
返回

我不确定这是否与原始海报的问题相同,因为我使用的是最近更新的boost库。
无论如何,我的解决方案是:

//端口打开步骤
端口=boost::共享端口
(新的boost::asio::串行_端口(io_服务_));
boost::线程t(boost::绑定(&boost::asio::io_服务::运行,&io_服务));
端口->异步读取部分(…);
.......
//端口关闭步骤
端口->取消();
端口->关闭();
端口重置();
io_服务_u.stop();

io_服务u.reset();//谢谢,我会试试看-但是当设备第一次打开时,读取不应该也失败吗?当驱动程序说RTS关闭时,读取将失败。何时发生取决于驱动程序实现。顺便说一句,当读取开始成功时:重新启动后,设备重新连接后,超时后?好的,我只是尝试设置RTS\u CONTROL\u DISABLE-它不会改变行为。串行端口::is_open返回true,但不会开始读取。其行为是:连接GPS,开始工具读取,断开GPS,读取停止,再次连接,仍不读取。重启工具:再次工作。谢谢,在close()之后检查is_open(),然后创建一个新实例修复了这个问题!看起来不错-我正在检查错误代码,但我还没有注意到native()方法。。。有了它,我应该能够以某种方式转换串行端口以读取:)也许你只是没有注意到设备被插入,因为usb驱动程序没有向操作系统报告这一点。在这种情况下:运气不好:/