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 ...
随机推荐
- [清华集训2015 Day1]主旋律-[状压dp+容斥]
Description Solution f[i]表示状态i所代表的点构成的强连通图方案数. g[i]表示状态i所代表的的点形成奇数个强连通图的方案数-偶数个强连通图的方案数. g是用来容斥的. 先用 ...
- 微信小程序之用户信息授权 wx.getUserInfo
用户授权 <button open-type="getUserInfo" bindgetuserinfo='getUser'>授权用户信息</button> ...
- 事务特性,事务的隔离级别,并发事务可能出现的问题,spring事务 数据库锁
1.0 事务特性(ACID) Atomicity:原子性,一个事务不可以被拆分 Consistency:一致性,在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是处于正确的状态, ...
- 开源微信Http协议Sdk【实现登录/获取好友列表/修改备注/发送消息】
基于微信Http协议封装的一个Sdk,目前实现了以下功能:. 1:扫码登录(检测二维码扫描状态) 2:获取最近联系人.群组.所有联系人 3:修改好友备注 4:给好友发送消息 暂且这么多,也没多余的时间 ...
- 强化学习算法Policy Gradient
1 算法的优缺点 1.1 优点 在DQN算法中,神经网络输出的是动作的q值,这对于一个agent拥有少数的离散的动作还是可以的.但是如果某个agent的动作是连续的,这无疑对DQN算法是一个巨大的挑战 ...
- 最近在研究google的angularjs
最近在研究google的angularjs,先做个简单的例子来试试. <!doctype html> <html lang="en" ng-app="m ...
- 全局最小割StoerWagner算法详解
前言 StoerWagner算法是一个找出无向图全局最小割的算法,本文需要读者有一定的图论基础. 本文大部分内容与词汇来自参考文献(英文,需***),用兴趣的可以去读一下文献. 概念 无向图的割:有无 ...
- Scalable Object Detection using Deep Neural Networks译文
原文:https://arxiv.org/abs/1312.2249
- SDN交换机迁移2
关于迁移过程中迁移目标(被迁移的交换机和目标控制器)的选择 SDN中基于过程优化的交换机竞争迁移算法 通信学报 交换机:请求速率大于域内平均请求速率的交换机集合: 控制器:综合网络中时延.流量和控制器 ...
- 腾讯云申请的64位ubuntu服务器配置php环境
腾讯云申请的64位ubuntu服务器配置php环境 一.首先还是安装Lamp组合 Linux+Apache+Mysql+php 直接命令 sudo apt-get install apache2 su ...