所以我尝试了 boost::asio 并测试了阻塞回声示例。他们似乎并没有完全阻止它。至少不是我预期的那样。
是否有可能摆脱任何类型的缓冲,或者您可以拥有的最小缓冲区大小是多少?看起来 10000 字节太小了。
以下代码在阻塞之前运行了 2 次写入。如果我在写入中添加 boost::asio::transfer_exactly(10000) 参数,它仍然是 2。boost::asio::transfer_exactly(5000) 让我写入 5 次。
那么这个网络/io/asio 东西是如何工作的呢?就像我只想发送一个字节并等待它到达另一端,而不需要任何额外的通信。
服务器:
boost::asio::io_service io_service;
tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), 12346));
tcp::socket sock(io_service);
a.accept(sock);
sock.non_blocking(false);
boost::asio::socket_base::send_buffer_size option(10000);
sock.set_option(option);
while(true) {
char data[10000];
boost::asio::socket_base::bytes_readable bytes_readable_cmd(true);
sock.io_control(bytes_readable_cmd);
std::size_t bytes_readable = bytes_readable_cmd.get();
if(bytes_readable) {
/**/
}
boost::asio::write(sock, boost::asio::buffer(data, 10000));
printf("#\n");Sleep(10);
}
客户:
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query(tcp::v4(), "localhost", "12346");
tcp::resolver::iterator iterator = resolver.resolve(query);
tcp::socket sock(io_service);
boost::asio::connect(sock, iterator);
sock.non_blocking(false);
最佳答案
我认为在这种情况下,write
实际上只有在底层缓冲区已满时才会阻塞。
这句话来自msdn在这里是合适的:
The successful completion of a send function does not indicate that the data was successfully delivered and received to the recipient. This function only indicates the data was successfully sent.
If no buffer space is available within the transport system to hold the data to be transmitted, send will block unless the socket has been placed in nonblocking mode.
我尝试写入超过 64KB(刚好从 65537 开始),但它在第一次调用时就阻塞了。
这不是 Asio 的工作方式,而是 TCP 和套接字的工作方式。这answer也可能有帮助。
我想您需要明确地从客户端发送回执确认,即滚动您自己的应用层协议(protocol)。
关于c++ - 关于 boost::asio 套接字和阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10545652/