boost:asio与 TCP通信

1059 篇文章 275 订阅

asio支持TCP、UDP、ICMP等通信协议,它在名字空间boost::asio::ip里提供了大量的网络通信方面的函数和类,很好的封装了Socket API

TCP

  • 类ip::tcp是asio网络通信(TCP)部分主要的类,表示TCP协议。
    • 它本身并没有太大功能,而是定义了很多用于TCP通信的typedef类型,用来协作完成网络通信。它更像是一个名字空间
    • 这些typedef包括端点类endpoint、套接字类socket、接收器acceptor、解析器resolver、流类iostream等
    • 需引入头文件: < boost/asio/ip/tcp.hpp>

类摘要

在这里插入图片描述

示例

address

IP地址独立于TCP/UDP等通信协议,asio使用类ip::address来表示IP地址,可以同时支持IPv4、IPv6两种类型

类摘要

在这里插入图片描述
在这里插入图片描述

  • from_string():从字符串产生IP地址
  • to_string():将IP地址转换成字符串

示例

在这里插入图片描述

IP地址分为IPv4和IPv6两种,在Boost.Asio中分别由ip::address_v4和ip::address_v6表示,并提供了ip::address作为版本无关的IP地址表示。

#include <iostream>
#include <boost/asio.hpp>

using namespace boost::asio;

int main() {
    
    // ip::address:from_string(str):这个函数根据一个IPv4地址(用.隔开的)或者一个IPv6地址(十六进制表示)创建一个地址。
    ip::address addr = ip::address::from_string("192.168.135.1");
    assert(addr.is_v4());
    std::cout << "addr.is_v4():\t" << addr.is_v4() << std::endl;
    std::cout << "addr.to_string():\t" << addr.to_string() << std::endl;


    addr = addr.from_string("ABCD:EF01:2345:6789:ABCD:EF01:2345:6789");
    assert(addr.is_v6());
    std::cout << "addr.to_string():\t" << addr.to_string() << std::endl;


    getchar();
    return 0;
}

endpoint

有了IP地址,再加上端口号就构成了一个socket端点,在asio库中用ip::tcp::endpoint来表示

类摘要

在这里插入图片描述
在这里插入图片描述

示例

在这里插入图片描述

socket

socket类是TCP通信的基本类,它是basic_stream_socket的TCP协议特化

类摘要

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • send()/receive()与write_some()/read_some()功能完全一致,内部都是调用系统函数sendmsg()/recvmsg()
  • socket读写函数的参数都是buffer类型,可以用buffer()函数包装各种容器适配,区别在于send()/write_some()的参数是一个可读buffer,而receive()/read_some()要求是可写buffer
  • async_xxx()可以使用两种形式的handler

在这里插入图片描述

acceptor

acceptor类对应Socket API的accept功能,它用于服务端,在指定的端口处接受连接,必须配合socket类才能完成通信。

acceptor是basic_socket_acceptor的TCP协议特化:

在这里插入图片描述

在这里插入图片描述

resolver

resolver类对应Socket API的getaddrinfo()系列函数,用于解析网址获得可用的IP地址(使用应用中一般只有一个域名),解析得到的IP地址可以使用的socket对象连接

类摘要

resolver是basic_resovler的TCP协议特化

在这里插入图片描述
在这里插入图片描述

示例

协程yield_context

协程是泛化的例程:

  • 例程只有一个入口和多个出口。比如说函数,从最开始的函数入口开始,可以在某个时刻用return泛话,例程就结束了
  • 协程有多个入口多个出口,从最开始的入口进入之后可以随时用yield调用返回,之后再调用协程就会从刚才返回的地方继续执行

boost中使用协程需要头文件< boost/asio/spawn.hpp>,并链接libboost_context.a、libboost_coroutine.a、libboost_thread.a

类摘要

asio协程主要类是yield_context,它是basic_yeild_context的typedef

在这里插入图片描述

  • yield_context的接口很简单,它保存了协程的运行环境,交替执行主协程和从协程,达到异步的目的。
  • operator[]用于外部获取发生的错误码,如果不适用operator[]则会抛出system_error异常来报告错误
  • yield_context可以替代handler,async_xxx()函数就不需要写回调函数了,而是使用yield_context对象。async_xxx()调用后会自动交出控制权,执行其他的协程,直到异步操作完成时才会返回继续执行之后的动作

通常我们并不直接创建yield_context对象,而是使用spawn()。它产生yield_context_对象,再传递给使用yield_context的函数:
在这里插入图片描述

实例

在这里插入图片描述
在这里插入图片描述

这里在一个for循环里循环监听端口,但是它是在spawn()里利用协程实现的,接收连接和发送数据使用的是异步的async_accept和async_write_some,这样在每个异步调用处并不会阻塞,而是转入其他的协程。

流操作

对于TCP通信,asio库提供了一个ip::tcp::iostream类来简化socket通信。

客户端

在这里插入图片描述

服务端

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值