020857d4b858378d3cc5789a4b31850c
Go Ethereum P2P : 实现[3] server inbound 实现分析


在本章的第一节分析了 p2p server.go 的基本架构
在本章的第二节分析了 p2p rlpx 协议 的原理
接下来我们再从数据流的角度来理顺整体的过程

Server 作为inbound的入口分析

数据从Socket 读取上来的入口位置(p2p/server.go)

作为第一步, Server Start 函数创建的 go routine srv.setupListening() 来负责完成对Socket的传统的 listen/accept 操作

然后我们跳转到srv.setupListening()


在Line 574 处, 完成了Listen的传统操作, 接下来更进一步的操作又转而进入了另外一个新创建的 go routine srv.listenLoop(). 这里是更进一步的详细的实现

在listenLoop()中 首先限定了同时最大的连接数defaultMaxPendingPeers(50)。 通过一个缓冲的Channel来实现。 再每一次进行accept之前 都需要首先查看是channel中是否还有空闲的slot。 然后调用Accpet 之后完成一些必要的记录工作再开启一个新的go routine SetupConn 来继续完成每一个连接的数据处理。

  1. 在这里从 Channel slots 获取一个空闲位置
  2. 在这里调用Accept
  3. 创新go routine SetupConn

接下来就是在SetupConn 函数中初始化 connection 。

这里 唯一值得注意的是srv.Newtransport 其实在srv.Start()函数在初始化时已经指向了RLPX协议栈。
我们可以回溯到这里的代码。

所以后续所有在conn 对象中调用的相关握手,读写的操作其实都已经导向到了rlpx 协议栈
TODO rlpx 接口分析
之后在SetupConn中就导向了一个inbond/outbond 公用的函数setupConn
这里包含了最核心的实现。 最主要有4个步骤(只考虑inbond)。

top Created with Sketch.