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 ...
随机推荐
- python 字符串的split()函数详解
split翻译为分裂. split()就是将一个字符串分裂成多个字符串组成的列表. split()当不带参数时以空格进行分割,当代参数时,以该参数进行分割. //---当不带参数时 example: ...
- 2_C语言中的数据类型 (十)数组
1 字符串与字符数组 1.1 字符数组定义 char array[100]; 1.2 字符数组初始化 char array[100] = {'a', 'b', ...
- [CF963E]Circles of Waiting[高斯消元网格图优化+期望]
题意 你初始位于 \((0,0)\) ,每次向上下左右四个方向走一步有确定的概率,问你什么时候可以走到 以 \((0,0)\)为圆心,\(R\) 为半径的圆外. \(R\le 50\) 分析 暴力 \ ...
- 【Orleans开胃菜系列1】不要被表象迷惑
[Orleans开胃菜系列1]不要被表象迷惑 /** * prism.js Github theme based on GitHub's theme. * @author Sam Clarke */ ...
- zooland 新开源的RPC项目,希望大家在开发的微服务的时候多一种选择,让微服务开发简单,并且容易上手。
zooland 我叫它动物园地,一个构思很长时间的一个项目.起初只是觉得各种通信框架都封装的很好了,但是就是差些兼容,防错,高可用.同时在使用上,不希望有多余的代码,像普通接口一样使用就可以了. 基于 ...
- JavaScript快速入门-ECMAScript对象介绍
一.概念介绍 在 ECMAScript 中,所有对象并非同等创建的.一般来说,可以创建并使用的对象有三种:本地对象.内置对象和宿主对象. 要理解这三种对象,先要理解宿主环境. 1.宿主环境 一般宿主环 ...
- REST-framework快速构建API--四部曲
代码目录结构: 一.使用原生APIView 使用rest-framework原生的APIView实现过程: 以url(r'^books/$', views.BookView.as_view(),nam ...
- vs2013 std::sort 分析
由于之前在debug模式下发现stl的sort简直慢到不能忍,所以自己写了一个sgi的sort,后来发现在release模式下,vs自带的sort快的不行,就研究了下. 这里有些和sgi-stl相通的 ...
- 设计模式 笔记 组合模式 Composite
//---------------------------15/04/16---------------------------- //Composite 组合模式----对象结构型模式 /* 1:意 ...
- 高精度减法--C++
高精度减法--C++ 仿照竖式减法,先对其,再对应位相减. 算法处理时,先比较大小,用大的减小的,对应位再比较大小,用于作为借位符. #include <iostream> #includ ...