之前也看过asio的实现,还分析过asio底层的类结构。这一次要在项目中用asio做为网络底层的库,所以再次深入了解了一下asio内部的实现。
ip::tcp::socket是asio中对tcp连接socket的封装,提供了四个接口用于读写数据
- socket.write_some阻塞发送数据->将所有数据写入tcp/ip协议缓存中才返回
- socket.read_some阻塞接收数据->知道从协议层读取到数据才返回
- socket.async_write_some, 异步发送数据,asio中并非用的socket的非阻塞模式,而是用的windows中的overlapped io,当操作成功时,会用回调的方式返回。
- socket.async_read_some. 异步接收数据,当数据到达后,会调用回调通知。底层也是利用的overlapped io.
还有两个自由函数boost::asio::async_read, boost::asio::async_write,是对上面两个异步接口的封装。会循环上面的发送或者读取操作,知道填入的buffer已满为止。
这里说一下 非阻塞模式,和重叠io下的socket在使用上的不同。
首先两种方法都可以实现异步操作,不需要阻塞等待数据发送完毕才返回。不同点:
- 非阻塞socket在tcp/ip层数据已经满了时,调用send会返回SOCKET_ERROR,WSAGetLastError返回WSAEWOULDBLOCK表明协议缓存层已经满了,不能够在发了,再次调用时,还是会报同样的错误,数据无法发送。需要等待。
- 重叠io则不同,必须要用WSASend接口投