什么意味着阻止boost :: asio :: write?

时间:2023-01-28 20:58:53

I'm using boost::asio::write() to write data from a buffer to a com-Port. It's a serial port with a baud rate 115200 which means (as far as my understanding goes) that I can write effectively 11520 byte/s or 11,52KB/s data to the socket.

我正在使用boost :: asio :: write()将数据从缓冲区写入com-Port。这是一个波特率为115200的串口,这意味着(根据我的理解)我可以有效地将11520字节/秒或11,52KB / s的数据写入套接字。

Now I'm having a quite big chunk of data (10015 bytes) which i want to write. I think that this should take little less than a second to really write on the port. But boost::asio::write() returns already 300 microseconds after the call with the transferred bytes 10015. I think this is impossible with that baud rate?

现在我有一大堆数据(10015字节),我想写。我认为这应该花费不到一秒的时间来真正写入端口。但是,在调用传输的字节10015之后,boost :: asio :: write()返回已经300微秒。我认为这是不可能的波特率?

So my question is what is it actually doing? Really writing it to the port, or just some other kind of buffer maybe, which later writes it to the port.

所以我的问题是它到底在做什么?真的把它写到端口,或者只是其他类型的缓冲区,然后将其写入端口。

I'd like the write() to only return after all the bytes have really been written to the port.

我希望write()只在所有字节都写入端口后才返回。

EDIT with code example:

用代码示例编辑:

The problem is that i always run into the timeout for the future/promise because it takes alone more than 100ms to send the message, but I think the timer should only start after the last byte is sent. Because write() is supposed to block?

问题是我总是遇到未来/承诺的超时,因为它只需要超过100毫秒来发送消息,但我认为定时器应该只在最后一个字节发送后才开始。因为write()应该阻止?

void serial::write(std::vector<uint8_t> message) {
  //create new promise for the request
  promise = new boost::promise<deque<uint8_t>>;
  boost::unique_future<deque<uint8_t>> future = promise->get_future();
  // --- Write message to serial port --- //
  boost::asio::write(serial_,boost::asio::buffer(message));
  //wait for data or timeout
  if (future.wait_for(boost::chrono::milliseconds(100))==boost::future_status::timeout) {
    cout << "ACK timeout!" << endl;
    //delete pointer and set it to 0
    delete promise;
    promise=nullptr;
  }
  //delete pointer and set it to 0 after getting a message
  delete promise;
  promise=nullptr;
}

How can I achieve this? Thanks!

我怎样才能做到这一点?谢谢!

1 个解决方案

#1


In short, boost::asio::write() blocks until all data has been written to the stream; it does not block until all data has been transmitted. To wait until data has been transmitted, consider using tcdrain().

简而言之,boost :: asio :: write()会阻塞,直到所有数据都写入流中;它不会阻塞,直到所有数据都已传输完毕。要等到数据传输完毕,请考虑使用tcdrain()。

Each serial port has both a receive and transmit buffer within kernel space. This allows the kernel to buffer received data if a process cannot immediately read it from the serial port, and allows data written to a serial port to be buffered if the device cannot immediately transmit it. To block until the data has been transmitted, one could use tcdrain(serial_.native_handle()).

每个串行端口在内核空间中都有一个接收和发送缓冲区。如果进程无法立即从串行端口读取数据,则允许内核缓冲接收的数据,并且如果设备无法立即传输,则允许写入串行端口的数据进行缓冲。要阻止数据传输,可以使用tcdrain(serial_.native_handle())。

These kernel buffers allow for the write and read rates to exceed that of the transmit and receive rates. However, while the application may write data at a faster rate than the serial port can transmit, the kernel will transmit at the appropriate rates.

这些内核缓冲区允许写入和读取速率超过发送和接收速率。但是,虽然应用程序可能以比串行端口可以传输的更快的速率写入数据,但内核将以适当的速率进行传输。

#1


In short, boost::asio::write() blocks until all data has been written to the stream; it does not block until all data has been transmitted. To wait until data has been transmitted, consider using tcdrain().

简而言之,boost :: asio :: write()会阻塞,直到所有数据都写入流中;它不会阻塞,直到所有数据都已传输完毕。要等到数据传输完毕,请考虑使用tcdrain()。

Each serial port has both a receive and transmit buffer within kernel space. This allows the kernel to buffer received data if a process cannot immediately read it from the serial port, and allows data written to a serial port to be buffered if the device cannot immediately transmit it. To block until the data has been transmitted, one could use tcdrain(serial_.native_handle()).

每个串行端口在内核空间中都有一个接收和发送缓冲区。如果进程无法立即从串行端口读取数据,则允许内核缓冲接收的数据,并且如果设备无法立即传输,则允许写入串行端口的数据进行缓冲。要阻止数据传输,可以使用tcdrain(serial_.native_handle())。

These kernel buffers allow for the write and read rates to exceed that of the transmit and receive rates. However, while the application may write data at a faster rate than the serial port can transmit, the kernel will transmit at the appropriate rates.

这些内核缓冲区允许写入和读取速率超过发送和接收速率。但是,虽然应用程序可能以比串行端口可以传输的更快的速率写入数据,但内核将以适当的速率进行传输。