1. 云栖社区>
  2. >
  3. 正文

boost异步网络通信初探

作者:用户 来源:互联网 时间:2016-01-20 19:47:39

网络内存管理数据线程函数this

boost异步网络通信初探 - 摘要: 本文讲的是boost异步网络通信初探, 说到异步, 即不用新开线程, 可以在同一个线程里使用. 而异步即是适时执行回调而已. 这时候什么时候执行回调,而且还要在同一个线程调用就至关重要了. 那boost如何能做到有消息到来就可以通知到接收函数这一点的呢? 这里的原理就在

说到异步, 即不用新开线程, 可以在同一个线程里使用. 而异步即是适时执行回调而已. 这时候什么时候执行回调,而且还要在同一个线程调用就至关重要了. 那boost如何能做到有消息到来就可以通知到接收函数这一点的呢? 这里的原理就在于其”通知”功能其实是使用的循环检测. 怎么说呢? 处理网络数据在其它进程里面, 分发到对应线程里面. 不过这个操作是阻塞操作. 不过不在用户自己的线程中就不会影响到用户线程. boost.asio使用boost::asio::io_service负责异步处理网络数据的读取与分发.

io_service与网络通信的线程间应该共享了个消息队列之类的东西, 通信线程负责放东西, io_service负责读东西 下面两个是io的实际执行函数

io_service::run() 阻塞调用, 有数据要发送立即发出去不等待发送完成, 取不到数据就等在那里
io_service::poll() 发数据一样, 不过取不到数据立即返回

(注:以上是我直观的理解,没有科学根据)

这样的话io_service::poll()需要被放到游戏循环的update或者窗口消息处理的MessageBump里面去 而run的版本, 如果有需要把网络通信放到另外一个线程, 而又不想自己update, 就直接使用run吧 剩下的内容就是读写网络数据, boost::asio设计得非常巧妙的一点是, 使用下面的方式:

void XXXClass::read(std::shared_ptr socket) {
    auto buf = std::make_shared<vector>();
    buf->resize(256);
    socket->async_read_some(asio::buffer(*buf), [this, socket, buf](system::error_code code, size_t len) {
        if (code.value()) {
            this->errHandler(code, socket);
            return;
        }
        string str;
        str.assign(buf->begin(), buf->begin() + len);
        this->notifyReaders(RecvStatusCode::OK, str);
        this->read(socket);  // 注意这里
    });
}

拿socket进行端对端的通信 在当前接收的回调函数执行时, 注册下一个读取的回调, 效果即是实现了不停地读取同一个socket也就是同一个端(客户端/服务端)

之后还需要注意就是内存管理问题, 网络数据缓冲区必须使用堆分配, 因为不等待接收/发送完成 socket也需要被new出来, 在前后两次通信中需要不断被传递. 当错误发生时, 需要干掉socket。

以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索网络 , 内存管理 , 数据 , 线程 , 函数 this boost网络通信库、boost udp 异步、boost asio 异步、boost socket 异步、boost异步,以便于您获取更多的相关知识。

弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率

40+云计算产品,6个月免费体验

现在注册,免费体验40+云产品,及域名优惠!

云服务器9.9元/月,大学必备