C++的网络通信
基于C++的网络库有不少比如muduo,libevent等。muduo是感觉写的最容易理解的,boost中的asio的源码真的有些复杂,目前的主要目的还是知道怎么使用asio这个库,因为boost大部分都可能成为C++以后版本的标准。所以先来熟悉一下。
Asio中常用的类型
-
boost::asio::io_context
asio中基本所有的class在构造的时候都需要io_context作为参数。 -
boost::asio::ip::tcp::acceptor
-
boost::asio::ip::tcp::socket
同样,上面两个类型中的tcp可以换成udp -
boost::asio::strand<>
-
boost::asio::io_context::strand
确保在多线程下,按顺序执行
常用函数
asio的函数大部分都分为同步函数和异步函数,这里只介绍异步函数
async_accept
回调函数:
std::function<void(const boost::system::error_code& ec)>
ec指该异步函数有没有错误
async_connect
std::function<void(const boost::system::error_code& ec, size_t bytes)>
socket.async_read_some
其中第一个参数是boost::asio::buffer, buffer只是对已有buffer的封装并不会alloc新的空间。
回调函数:
std::function<void(const boost::system::error_code& ec, size_t bytes)>
参数 | 意义 |
---|---|
ec | error code |
bytes | 读到的字节数。该字节数与发送的字节数并不一定相等,可能需要多次的回调才能最终读完 |
- 例子
我自有的buffer只有10个字节,而对方发送了28个字节
std::vector<char> input(10);
socket_.async_read_some( boost::asio::buffer(input), [](const boost::system::error_code& ec, size_t bytes){
std::cout << bytes << std::endl;
} );
这种情况下,如果只有一个连接,没有其他资源占有,回调会调用三次,其中bytes分别等于10,10和8
socket.async_write_some
回调函数:
std::function<void(const boost::system::error_code& ec, size_t bytes)>
参数 | 意义 |
---|---|
ec | error code |
bytes | 已经发送的字节数。该字节数和buffer中的大小不一定相等。 |