Boost Asio:检查套接字的可读写能力
Boost Asio: checking socket ability to be readable/writable
在我的应用程序中,我必须混合使用asio创建的套接字和本机套接字(来自C posgresql库)。
我需要的是能够从特定套接字上的boost的io_service类实例中获得通知,使其处于非阻塞可读/写状态,但无需执行实际的读/写(将由第三方库完成),即只有效地执行选择()/轮询
将0作为缓冲区长度传递给async_read_some()这样的函数可以实现吗?
我做了一个快速测试,实际上,对缓冲区长度为零的async_read_some()的调用确实调用了读取事件处理程序,但我不确定它是在相应的套接字句柄上的select中阻塞后完成的,等待真正的"可以读取"状态。
这通常被称为反应堆式操作。
这些可以通过向异步操作提供CCD_ 1来获得。Reactor风格的操作提供了一种通知何时可以执行读或写操作的方式,并且对于与第三方库集成、使用共享内存池等非常有用。Boost.Asio文档提供了一些信息和以下示例代码:
ip::tcp::socket socket(my_io_service);
...
socket.non_blocking(true);
...
socket.async_read_some(null_buffers(), read_handler);
...
void read_handler(boost::system::error_code ec)
{
if (!ec)
{
std::vector<char> buf(socket.available());
socket.read_some(buffer(buf));
}
}
Asio还提供了一个官方的非阻塞示例,说明了如何与希望直接在套接字上执行读写操作的库集成。
为操作提供零长度缓冲区通常会导致无操作,因为操作的完成条件将在不尝试执行任何I/O的情况下得到满足。以下是一个完整的例子,展示了两者之间的区别:
#include <array>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
// This example is not interested in the handlers, so provide a noop function
// that will be passed to bind to meet the handler concept requirements.
void noop() {}
void print_status(
const boost::system::error_code& error,
std::size_t bytes_transferred,
boost::asio::ip::tcp::socket& socket)
{
std::cout << "error: " << error.message() << "; "
"transferred: " << bytes_transferred << "; "
"available: " << socket.available() << std::endl;
}
int main()
{
using boost::asio::ip::tcp;
// Create all I/O objects.
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 0));
tcp::socket socket1(io_service);
tcp::socket socket2(io_service);
// Connect the sockets.
acceptor.async_accept(socket1, boost::bind(&noop));
socket2.async_connect(acceptor.local_endpoint(), boost::bind(&noop));
io_service.run();
io_service.reset();
std::array<char, 512> buffer;
// Reading into a zero-length buffer is a no-op and will be
// considered immediately completed.
socket1.async_receive(boost::asio::buffer(buffer, 0),
boost::bind(&print_status,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred,
boost::ref(socket1))
);
// Guarantee the handler runs.
assert(1 == io_service.poll());
io_service.reset();
// Start a reactor-style read operation by providing a null_buffer.
socket1.async_receive(boost::asio::null_buffers(),
boost::bind(&print_status,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred,
boost::ref(socket1))
);
// Guarantee that the handler did not run.
assert(0 == io_service.poll());
// Write to the socket so that data becomes available.
boost::asio::write(socket2, boost::asio::buffer("hello"));
assert(1 == io_service.poll());
}
输出:
error: Success; transferred: 0; available: 0
error: Success; transferred: 0; available: 6
相关文章:
- 用C++快速读写文件
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 在一个读写器队列中,我可以用volatile替换原子吗
- C++套接字对不读/写父/子
- 如何调试读写器锁的死锁?
- 在两个线程上读/写 64 位,无互斥/锁定/原子
- Linux 挂载使用重新挂载以允许读写
- C++中读/写二进制文件
- 如何读/写或遍历 std::array 中的特定元素范围?
- 内存排序或读取-修改-写入操作,仅(读/写)内存顺序
- USB-HID 读/写(重叠)等待单个对象不返回C++
- 为什么使用_access时只读测试对读写文件有效
- Boost::Asio串行读/写打开:参数不正确
- 读/写 OpenMP 中的共享向量会减慢程序速度
- 谷歌测试读写同一文件失败
- Android USB 附件模式无法使用 libusb 与主机 PC 一起读/写
- 特定时间间隔 C++ 上的读写日志
- SQLite - C++中的多线程读写
- Boost Asio:检查套接字的可读写能力