eos 源码net_plugin分析
1 net_plugin_impl::connect(connection_ptr c) 函数用于解析地址,内部异步回调async_resolve

async_resolve 传递了lambda表达式,如果err为零,则调用connect连接指定的地址
2 void net_plugin_impl::connect( connection_ptr c, tcp::resolver::iterator endpoint_itr ) 该函数将connection连接指定地址
内部调用async_connect进行异步连接,如果连接成功,回调lambda表达式。lambda表达式中取出connection的weak_ptr,这么做为防止shared_ptr互相引用导致内存无法释放。如果连接失败关闭socket连接,如果地址错误关闭socket重新连接。
连接成功后,调用start_session,开始监听该描述符的读事件,并且开始发送握手消息send_handshake()
3 bool net_plugin_impl::start_session( connection_ptr con )
开始连接,内部调用start_read_message(),并且增加连接会话数量。
4 void net_plugin_impl::start_read_message( connection_ptr conn ) 读取消息函数,内部较为复杂。
内部将shared_ptr connection_ptr 赋值给connection_wptr(weak_ptr)类型变量weak_conn,也是为了防止互相引用shared_ptr造成内存无法回收,minimum_read为要读取的字节数,如果conn->outstanding_read_bytes 非0,则等于conn->outstanding_read_bytes,否则等于消息头大小。同时判断是否设置低水位标记,如果设置了低水位标记,则将低水位大小设置为取minimum_read和固定的max_socket_read_watermark的最小值。同时实现lambda表达式赋值给completion_handler,completion_handler主要功能判断传输字节是否全部传输完成。未完成,则返回差值。
5 接着 void net_plugin_impl::start_read_message( connection_ptr conn )内部调用了async_read,设置异步读取数据,有消息到来会触发回调lambada表达式。当completion_handler返回0停止读取。lambda函数内部,conn->outstanding_read_bytes.reset()重置请求等状态,
conn->pending_message_buffer.bytes_to_write()表示pending_message_buffer剩余空间,还可读取多少数据。
conn->pending_message_buffer.
conn->pending_message_buffer.bytes_to_read() 表示pending_message_buffer已经读取多少 字节,用户需要从
pending_message_buffer中读取多少。
conn->outstanding_read_bytes表示buffer还有多少字节没有读取。
判断bytes_transferred > conn->pending_message_buffer.bytes_to_write(),视为异常,因为可用空间不足了 ,没办法接收。
conn->pending_message_buffer.advance_write_ptr(bytes_transferred); 将写指针向后推进bytes_transferred字节。
write_ptr指向了pending_message_buffer的可用空间。bytes_to_write()返回可用字节数。
如果conn->pending_message_buffer.bytes_to_read() > 0,则会一直循环,直到读完buffer中所有数据。
如果bytes_in_buffer < message_header_size,则将头部未读取的数据放入outstanding_read_bytes中。否则说明读完包头数据,pending_message_buffer.peek,读取4字节数据写入message_lenghth,确定数据大小。
auto total_message_bytes = message_length + message_header_size;为整个数据包大小,bytes_in_buffer >= total_message_bytes 说明此时buffer已经接受完数据,调用 conn->process_next_message()处理。否则,就将剩余未读完的数据放入outstanding_read_bytes中,
available_buffer_bytes表示可用字节数,如果可用字节数不足,则扩充pending_message_buffer大小。
6 bool connection::process_next_message(net_plugin_impl& impl, uint32_t message_length)处理消息。
位移代码没看明白,注释的意思是保存序列化前的原始信息。之后,blk_buffer.resize(message_length);重新设置大小为message_length长度,
auto index = pending_message_buffer.read_index();找到当前的读索引,peek函数将message_length长度的数据读入blk_buffer中。
之后创建datastream ds用来反序列化。将消息写入net_message中。接着定义了msgHandler 对象m,构造函数中传入net_plugin_impl和connection共享指针,调用msg.visit(m)。msgHandler的定义和实现
msgHandler重载了()运算符,当类msgHandler对象传参(msg)时会调用impl.handle_message(c,msg)。如msgHandler h(msg)实际调用的
impl.handle_message(c,msg)。
net_message为static_variant类型,static_variant类中实现了visit函数
visit内部调用apply函数,apply函数内部调用了visitor对象传参data,visitor就是上一层的msgHandler。
net_plugin_impl::handle_message 根据参数传入不同,实现了不同的函数调用。
这就是所说的visitor模式。通过net_message(static_variant类型)调用封装的visit函数,visit内部调用了visitor对象的传参,只要重载()(param)就可以实现调用。msgHandler重载operator()(const T& msg),所以调用impl.handle_message(c,msg),而msg为不同类型,所以可实现上面的不同调用。
谢谢关注我的公众号

eos 源码net_plugin分析的更多相关文章
- 【精解】EOS标准货币体系与源码实现分析
EOS智能合约中包含一个exchange合约,它支持用户创建一笔交易,是任何两个基本货币类型之间的交易.这个合约的作用是跨不同币种(都是EOS上的标准货币类型)的,通过各自与EOS主链价值进行锚定,然 ...
- 1.EOS源码编译运行
目前网络上都是针对老版EOS2.0源码编译的文章,我在mac上参考这些文章编译,最后发现根本就不对,最新版本只需一条命令(./eosio_build.sh,依赖库会自动安装的)即可.我根据这些文章手动 ...
- MapReduce的ReduceTask任务的运行源码级分析
MapReduce的MapTask任务的运行源码级分析 这篇文章好不容易恢复了...谢天谢地...这篇文章讲了MapTask的执行流程.咱们这一节讲解ReduceTask的执行流程.ReduceTas ...
- Activity源码简要分析总结
Activity源码简要分析总结 摘自参考书籍,只列一下结论: 1. Activity的顶层View是DecorView,而我们在onCreate()方法中通过setContentView()设置的V ...
- MapReduce的MapTask任务的运行源码级分析
TaskTracker任务初始化及启动task源码级分析 这篇文章中分析了任务的启动,每个task都会使用一个进程占用一个JVM来执行,org.apache.hadoop.mapred.Child方法 ...
- TaskTracker任务初始化及启动task源码级分析
在监听器初始化Job.JobTracker相应TaskTracker心跳.调度器分配task源码级分析中我们分析的Tasktracker发送心跳的机制,这一节我们分析TaskTracker接受JobT ...
- MongoDB源码分析——mongod程序源码入口分析
Edit 说明:第一次写笔记,之前都是看别人写的,觉得很简单,开始写了之后才发现真的很难,不知道该怎么分析,这篇文章也参考了很多前辈对MongoDB源码的分析,也有一些自己的理解,后续将会继续分析其他 ...
- FFmpeg的HEVC解码器源码简单分析:解析器(Parser)部分
===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...
- FFmpeg源码简单分析:libswscale的sws_scale()
===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...
随机推荐
- Luogu P4322 [JSOI2016]最佳团体
JZdalao昨天上课讲的题目,话说JSOI的题目是真的不难,ZJOI的题目真的是虐啊! 题意很简单,抽象一下就是:有一棵树,一次只能选从根到某个节点上的链上的所有点,问从中取出k个节点所得到的总价值 ...
- LNMP环境中WordPress程序伪静态解决方案
LNMP环境是目前我们国内站长使用的Linux VPS配置环境中使用较多的.作为新手我们很可能会看到老左类似的"LNMP安装教程"然后依葫芦画瓢的去安装VPS.我们是否有发现环境中 ...
- python基础学习1-流程控制和判断
python for循环和 if流程控制用法 Ages=22 for i in range(10): inputAges = int(input("输入年龄")) if input ...
- bootstrap-validator基本使用(自定义验证身份证号和手机号)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- 线状地物图斑化全流程作业(使用ArcMap软件)
一.线状地物调整 1.添加全覆盖图斑数据 2.添加线状地物 3.添加地理图斑 4.添加村界 5.剪裁自己村界的线状地物得(地理处理/剪裁(输入要素为线状地物,剪裁要素为村界,输出要素是得到的新层位置) ...
- VRP基础及操作
VRP基础及操作 前言 通用路由平台VRP(Versatile Routing Platform)是华为公司数据通信产品的通用操作系统平台,它以IP业务为核心,采用组件化的体系结构,在实现丰富功能特性 ...
- centos上部署mysql
本文记录整个安装的过程和跳进的坑,大家预祝我能从坑里爬出来吧 当前系统版本 开始我们的安装: 在安装之前查阅了部分资料,大体安装流程 yum -y install mysql yum -y insta ...
- Linux内核分析作业 NO.2
操作系统是如何工作的 于佳心 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ...
- 20135327郭皓——Linux内核分析第二周 操作系统是如何工作的
操作系统是如何工作的 上章重点回顾: 计算机是如何工作的?(总结)——三个法宝 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的 ...
- Mybatis 从入门到精通一:mybatis的入门
1.Mybatis简介 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation(阿帕奇软件基金会) 迁移到了google ...