Serial port 奇怪的行为boost::使用串行端口异步写入

Serial port 奇怪的行为boost::使用串行端口异步写入,serial-port,boost-asio,Serial Port,Boost Asio,我正在尝试实现带超时的同步写入。我使用截止时间计时器和异步写入 代码: size\u t SerialBus::timeout\u write(std::vector&buf) { isWriteTimeOut=假; 字节\写入\等于0; //超时后&取消,似乎我们需要 //为后续读取操作执行重置。 端口获取io服务().reset(); //异步读取1个字符。 boost::asio::异步写入(端口),boost::asio::缓冲区(buf), boost::bind(&PLT::Seri

我正在尝试实现带超时的同步写入。我使用截止时间计时器和异步写入

代码:

size\u t SerialBus::timeout\u write(std::vector&buf)
{
isWriteTimeOut=假;
字节\写入\等于0;
//超时后&取消,似乎我们需要
//为后续读取操作执行重置。
端口获取io服务().reset();
//异步读取1个字符。
boost::asio::异步写入(端口),boost::asio::缓冲区(buf),
boost::bind(&PLT::SerialBus::write_complete),
这
boost::asio::占位符::错误,
boost::asio::占位符::字节(已传输);
//设置一个截止时间来实现我们的超时。
timerWrite_uu.expires_ufrom_unow(boost::posix_time::毫秒(timeout_u));
timerWrite.async\u wait(boost::bind(&PLT::SerialBus::timeOutWriteHandler),
这是boost::asio::占位符::error);
端口获取io服务()运行();
返回字节\u写入\u;
}
void SerialBus::timeOutWriteHandler(const boost::system::error\u代码和错误)
{
//超时被取消了吗?
如果(错误){
//对
isWriteTimeOut=假;
回来
}
//不,我们已经超时了,所以杀了他
//读取操作
//将调用读取回调
//出错
isWriteTimeOut_u3;=真;
端口“”取消();
}
void SerialBus::write_complete(常量boost::system::error_代码和错误,
大小(传输的字节数)
{
字节\写入\字节=传输的字节\字节;
errorCode=错误;
timerWrite_u2;.cancel();
}
我有同样的阅读功能

当我使用timeout_写入足够长的缓冲区时,计时器将过期。当发生此错误时,异步写入处理程序write complete get 995错误,传输的字节数为0,buf变为空(事实上它是同一类的成员,生命周期足够长),但数据被传输。当我调用timeout_read时,我从我的设备(FTDI)得到正确的答案。当缓冲区长度小于并在计时器之前调用write complete时,一切都正常(bufer详细说明了我在其中输入的内容)。当我使用同步版本的write it block COM时,直到我用usb电缆replug重新启动它

在这种情况下,我不知道如何确定什么是真正发送到设备或正确的取消传输。或者我需要使用本机函数来代替boost


我使用boost 1.58 Win7 x64和ftdi 2.12.00以及vs2010

,我不明白为什么同步版本会阻止端口,直到它拔出并没有发送所有数据,但异步不仅被计时器取消并发送一段数据,而且传输了所有数据错误995是错误\u操作\u中止,“由于线程退出或应用程序请求,I/O操作已中止“好吧,这就是你想要的,你得到了。将超时设置得太低是一个非常常见的错误,设备关闭握手的时间没有上限。仅用于检测总体设备故障,不要低于10秒。Boost.Asio的串行端口支持是一个非常薄的包装,因此本机函数可能会产生相同的结果。根据我的经验,根本问题通常是虚拟COM端口驱动程序无法像真正的COM端口一样正常工作。是的,我知道此错误是由超时调用的,可能只是诊断问题。但如果异步版本没有破坏端口式同步版本,并且如果我了解asio的来源,那么异步函数之间的区别使用多个winApi::writeFile(),但如果是这样,为什么不可能返回已传输的字节?无论如何,winApi::PurgeComm解决了我的问题。是的,看起来是同步版本的驱动程序问题。
size_t SerialBus::timeout_write(std::vector<byte>& buf)
{
    isWriteTimeOut_=false;
    bytes_writen_=0;

    // After a timeout & cancel it seems we need
    // to do a reset for subsequent reads to work.
    port_.get_io_service().reset();

    // Asynchronously read 1 character.
    boost::asio::async_write(port_, boost::asio::buffer(buf), 
        boost::bind(&PLT::SerialBus::write_complete, 
        this, 
        boost::asio::placeholders::error, 
        boost::asio::placeholders::bytes_transferred)); 

    // Setup a deadline time to implement our timeout.
    timerWrite_.expires_from_now(boost::posix_time::milliseconds(timeout_));
    timerWrite_.async_wait(boost::bind(&PLT::SerialBus::timeOutWriteHandler,
        this, boost::asio::placeholders::error));

    port_.get_io_service().run();

    return bytes_writen_;
}

void SerialBus::timeOutWriteHandler(const boost::system::error_code& error)
{
    // Was the timeout was cancelled?
    if (error) {
        // yes
        isWriteTimeOut_=false;
        return;
    }
    // no, we have timed out, so kill
    // the read operation
    // The read callback will be called
    // with an error
    isWriteTimeOut_=true;       
    port_.cancel();
}

void SerialBus::write_complete(const boost::system::error_code& error,
    size_t bytes_transferred) 
{
    bytes_writen_=bytes_transferred;
    errorCode_=error;
    timerWrite_.cancel();
}