因为它是用的boost :: ASIO发送如何丢弃数据? [英] How to discard data as it is sent with boost::asio?

查看:313
本文介绍了因为它是用的boost :: ASIO发送如何丢弃数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写一些code读取和使用的boost :: ASIO 类写入串行设备。然而,发送程序之间的多个字符串时,我注意到的数据在它被写入到串行端口,而不是作为数据从其他程序发送的顺序读取接收程序 - 如果我开始阅读数据几秒钟之后,我不明白,我此刻发送值,但那些被送到previously。我假设这是我怎么设置我的引起的boost ::支持ASIO :: serial_port

I'm writing some code that reads and writes to serial device using boost::asio class. However, when sending several strings between programs, I've noticed that on the receiving program the data is read in the order as it was written to the serial port, and not as the data is sent from the other program - If I start reading data some seconds later, I don't get the values that I am sending at the moment but those that were sent previously. I'm assuming this is caused by how I am setting up my boost::asio::serial_port:

int main(int argc, char const *argv[]){

    int baud=atoi(argv[1]);
    std::string pty=argv[2];

    printf("Virtual device: %s\n",pty.data());
    printf("Baud rate: %d\n",baud);

    boost::asio::io_service io;
    boost::asio::serial_port port(io, pty);
    port.set_option(boost::asio::serial_port_base::baud_rate(baud));

    // counter that writes to serial port in 1s intervals
    int val=0;
    while (1){
        std::string data=std::to_string(val);
        data+='\n';
        std::cout << data;
        write(port,boost::asio::buffer(data.c_str(),data.size()));
        sleep(1); 
        val++;
        data.clear();
    }

    port.close(); 
    return 0;
}

有没有办法强制过去的数据,以尽快为新的值发送到串行端口(我认为应该在code的写()部分完成)丢弃?

Is there a way to force past data to be discarded as soon as a new value is sent to the serial port (which I assume should be done on the write() part of the code)?

推荐答案

Boost.Asio的不提供冲洗串行端口的缓冲区更高级别的抽象。然而,这通常可以通过其平台特定的调用,如 <$ C $完成C> tcflush() PurgeComm() ,一个串口的<一个操作href=\"http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference/basic_serial_port/native_handle.html\"相对=nofollow>函数native_handle()。

Boost.Asio does not provide a higher-level abstraction for flushing a serial port's buffers. However, this can often be accomplished by having platform specific calls, such as tcflush() or PurgeComm(), operate on a serial port's native_handle().

每个串行端口有一个接收和发送缓冲器,并冲洗在一个或两个缓冲器的动作。例如,如果两个串行端口连接(的/ dev / PTS / 3 的/ dev / PTS / 4 )和节目 A 打开并写入的/ dev / PTS / 3 ,那么就只能刷新关联的缓冲区的/ dev / PTS / 3 (在的/ dev /接收数据PTS / 3 ,但是不能读取和数据写入的/ dev / PTS / 3 ,但不发送)。因此,如果程序 B 启动,打开的/ dev / PTS / 4 ,想读非过时的数据,然后程序 B 需要刷新接收缓冲器为的/ dev / PTS / 4 打开串口后。

Each serial port has a receive and transmit buffer, and flushing operates on one or both of the buffers. For example, if two serial ports are connected (/dev/pts/3 and /dev/pts/4), and program A opens and writes to /dev/pts/3, then it can only flush the buffers associated with /dev/pts/3 (data received on /dev/pts/3 but not read, and data written to /dev/pts/3 but not transmitted). Therefore, if program B starts, opens /dev/pts/4, and wants to read non-stale data, then program B needs to flush the receive buffer for /dev/pts/4 after opening the serial port.

下面是在CentOS运行一个完整的例子。当例子,作为一个作家运行时,它会写一个顺序越来越多的串行端口每秒一次。当例子,作为一个作家运行时,它会读取五个号码,睡眠5秒钟,刷新其缓冲区读取所有其他迭代:

Here is a complete example running on CentOs. When the example runs as a writer, it will write a sequentially increasing number to the serial port once a second. When the example runs as a writer, it will read five numbers, sleep for 5 seconds and flush its read buffer every other iteration:

#include <iostream>
#include <vector>
#include <boost/asio.hpp>
#include <boost/thread.hpp>

/// @brief Different ways a serial port may be flushed.
enum flush_type
{
  flush_receive = TCIFLUSH,
  flush_send = TCIOFLUSH,
  flush_both = TCIOFLUSH
};

/// @brief Flush a serial port's buffers.
///
/// @param serial_port Port to flush.
/// @param what Determines the buffers to flush.
/// @param error Set to indicate what error occurred, if any.
void flush_serial_port(
  boost::asio::serial_port& serial_port,
  flush_type what,
  boost::system::error_code& error)
{
  if (0 == ::tcflush(serial_port.lowest_layer().native_handle(), what))
  {
    error = boost::system::error_code();
  }
  else
  {
    error = boost::system::error_code(errno,
        boost::asio::error::get_system_category());
  }
}

/// @brief Reads 5 numbers from the serial port, then sleeps for 5 seconds,
///        flushing its read buffer every other iteration.
void read_main(boost::asio::serial_port& serial_port)
{
  std::vector<unsigned char> buffer(5);
  for (bool flush = false;; flush = !flush)
  {
    std::size_t bytes_transferred =
        read(serial_port, boost::asio::buffer(buffer));
    for (std::size_t i = 0; i < bytes_transferred; ++i)
      std::cout << static_cast<unsigned int>(buffer[i]) << " ";
    boost::this_thread::sleep_for(boost::chrono::seconds(5));
    if (flush)
    {
      boost::system::error_code error;
      flush_serial_port(serial_port, flush_receive, error);
      std::cout << "flush: " << error.message() << std::endl;
    }
    else
    {
      std::cout << "noflush" << std::endl;
    }
  }
}

/// @brief Write a sequentially increasing number to the serial port
///        every second.
void write_main(boost::asio::serial_port& serial_port)
{
  for (unsigned char i = 0; ; ++i)
  {
    write(serial_port, boost::asio::buffer(&i, sizeof i));
    boost::this_thread::sleep_for(boost::chrono::seconds(1));
  }
}

int main(int argc, char* argv[])
{
  boost::asio::io_service io_service;
  boost::asio::serial_port serial_port(io_service, argv[2]);
  if (!strcmp(argv[1], "read"))
    read_main(serial_port);
  else if (!strcmp(argv[1], "write"))
    write_main(serial_port);
}

与创建虚拟串行端口 socat

$ socat -d -d PTY: PTY:
2014/03/23 16:22:22 socat[12056] N PTY is /dev/pts/3
2014/03/23 16:22:22 socat[12056] N PTY is /dev/pts/4
2014/03/23 16:22:22 socat[12056] N starting data transfer loop with
                                 FDs [3,3] and [5,5]

同时启动读取和​​写入的例子:

Starting both the read and write examples:

$ ./a.out read /dev/pts/3 & ./a.out write /dev/pts/4
[1] 12238
0 1 2 3 4 noflush
5 6 7 8 9 flush: Success
14 15 16 17 18 noflush
19 20 21 22 23 flush: Success
28 29 30 31 32 noflush
33 34 35 36 37 flush: Success

正如在输出证明,数字仅在序列中跳过当阅读器刷新其读取缓冲器: 3 4 noflush 5 6 7 8 9冲洗14 15

这篇关于因为它是用的boost :: ASIO发送如何丢弃数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆