What does blocking mean for boost :: asio :: write?
I am using boost::asio::write()
to write data from a buffer to com-Port. This is a serial port with a baud rate of 115200 which means (as far as I understand) that I can efficiently write 11520 bytes / s or 11.52 kb / s to the socket.
Now I have a rather large chunk of data (10015 bytes) that I want to write. I think it will take a little less than a second to actually write to the port. But it boost::asio::write()
returns already 300 microseconds after the call with 10015 bytes transferred. I think this is not possible with this baud rate?
So my question is, what does it actually do? Really write it to the port, or perhaps just some other buffer, which later writes it to the port.
I would like it to write()
return only after all the bytes in have actually been written to the port.
EDIT with sample code:
The problem is I always run into a timeout for the future / promise because it only takes over 100ms to send the message, but I think the timer should only start after the last byte has been sent. Because it write()
should block?
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? Thank!
source to share
In short, it boost::asio::write()
blocks until all data has been written to the stream; it does not block until all data has been transferred . To wait for the transmission, use tcdrain()
.
Each serial port has a send and receive buffer in kernel space. This allows the kernel to buffer the received data if the process cannot read from the serial port immediately and allows data transferon the serial port is buffered if the device cannot transmit it immediately . You can use to block until data is transferred tcdrain(serial_.native_handle())
.
These kernel buffers allow write and read speeds to exceed the send and receive speeds. However, although the application can write data at a faster rate than the serial port can transmit, the kernel will transmit at the appropriate rates.
source to share