C1a0c3a1379d880990a1266eaa0f1128
Go Ethereum P2P : 实现[4] server outbound 实现分析

网络数据发送/接收 核心数据结构的分析

为了更好的理解数据发送的流程, 最好对相关的核心数据结构的关系有一个清晰的概念
geth的代码在这块设计的比较随意, 功能代码分布的比较散, 但是又关系紧密。环环相扣。
所以在这里我们首先来分析一下相关的数据结构

  1. MsgReaderWriter 这个一个非常的简单且基础的接口, 它本身由两个接口组成,一个是MsgReader, 一个是MsgWriter。 这两个接口对应的是两个函数ReadMsg, WriteMsg。 这是两个非常基础且重要的函数, 后续所有的相关的结构都要实现这两个函数。

  2. 其次 接口transport 在MsgReaderWriter 的接口之上又扩展出来传输层协议所必要的握手以及关闭的函数。

  3. rlpx则是一个实现了这个接口的具体的结构,也包括了ReadMsg, WriteMsg 函数

  4. 在rlpx之下, 网络通信的消息需要分帧, rlpxFrameRW就是关于分帧的实现, 同时最后实际的消息发送/接收也落在了其实现的 ReadMsg / WriteMsg 函数上。 这里做了实际上的压缩、加解密、发送的工作。

  5. conn 结构在这里解耦了tranport的具体实现, 实际geth中这里所有的conn的调用都会重定向到rlpx以及rlpxFrameRW。

  6. 同时为了上层应用实现不同的协议, 这里抽象出了Protocol接口, geth 实现了eth62, eth63 两种协议。但是协议扩展出来的结构protoRW实际上MsgWrite 部分是指向了Conn 继而传递到了 rlpxFrameRW 。

  7. ProtoRW 是一个具体的关于协议和IO链接起来的结构。 主要负责outbond数据, 其WriteMsg函数最终会重定向到 rlpxFrameRW.WriteMsg.

代码流程分析

以上的数据结构分析给出了结论, 但是我们还是需要回到代码中了解一下其中的过程

  1. 首先回到server.go的连接完成的最后一步,要生成新的Peer对象, 这是传入的参数c 是conn连接指针,srv.Protocols是服务器从配置信息得来的支持的协议集合。
top Created with Sketch.