go版本的ethereum源码:分析接收相邻节点发来的数据
Peer的run函数会开一个线程执行读取相邻节点发过来的数据

Peer struct代表与特定相邻节点的连接,与该节点数据的通信都是通过这个Peer结构来做的,Peer有rw *conn,读写数据即通过它。

不同协议的数据读写统一都是由p.rw.ReadMsg来做p.rw是conn类型。
conn执行的ReadMsg的实现是:


收到的协议相关的数据由default处理(见上图),先根据msg.Code找到收到的数据对应的协议对应的protoRW,然后将msg传给protoRW的in通道。注意这个protoRW结构,它是用来控制协议级别数据的通信(有p2p.Protocol这个成员),之前的Peer的rw是控制节点这个级别的数据通信。
Peer的protoRW是在节点间连接时设置的,本地节点和每个远程节点建立连接执行newPeer函数时,会执行matchProtocols函数根据本地节点支持的协议和远程节点支持的协议共有的部分生成map[string]*protoRW。


rw.in通道里的数据是通过调用protoRW的ReadMsg函数取出来的。

注意Peer的readLoop函数中执行的p.rw.ReadMsg()和ProtocolManager的handleMsg函数中执行的p.rw.ReadMsg实际不是同一个实现函数,前者是rlpxFrameRW的ReadMsg函数,后者是protoRW的ReadMsg函数。
网友评论