以太坊原理解析

[以太坊源码分析][p2p网络02]:启动底层网络以及监听TCP

2018-12-23  本文已影响0人  jea的笔记本

这一节介绍的是如何启动底层的p2p网络,和启动的p2p网络会做些什么。

启动的p2p网络会做三件事情:一是帮助本地节点发现网络中其他的远程节点,建立相邻节点列表,这里体现了p2p网络的结构化。二是监听网络中远程节点发送的建立TCP连接请求。三是向网络中的远程节点发起建立TCP连接请求。

这里主要先介绍监听TCP连接请求。TCP连接,有点类似于打电话。监听TCP连接请求,就像是在等待别人call你,你接通电话后,就建立了TCP连接。(TCP连接有三次握手过程)。在此之上,以太坊还使用了rlpx加密协议,来保障节点之间通信的安全。

接下来是代码方面的说明。

0.索引

01.以太坊p2p模块的目录对应功能
02.Server的介绍
03.Start 启动p2p网络
04.监听TCP连接的过程
05.总结

1.以太坊p2p模块的目录对应功能

省略了测试用的文件。

p2p/
  discover/          基于UDP的节点发现V4协议
  discv5/            节点发现V5协议
  enode/             节点信息
  enr/               以太坊节点记录(ethereum node records)
  nat/               网络地址转换,用于内网穿透
  netutil/
  protocol/
  simulations/       本地p2p网络的模拟器
  dial.go            建立连接请求,以任务的形式 
  message.go         定义了读写的接口
  metrics.go         计时器和计量器工具
  peer.go            节点
  protocol.go        子协议
  rlpx.go            加密传输协议 
  server.go          底层p2p网络的函数入口 

以太坊的p2p网络位于go-ethereum/p2p目录下,该目录下的server.go是以太坊p2p网络的文件入口。server.go里定义了Server服务。Server服务对应了p2p底层网络的实现。

2.Server的介绍

Serverp2p/server.go中的核心结构体,用来管理所有连接的peer。这里的peer指的是一个共同建立p2p网络的远程节点。

type Server struct {...}

Server结构体中包含了Config配置,running运行状态标志,ntab节点发现的数据表等字段。

Server实现的方法:

其中,最重要的是Start方法,也就是p2p底层网络启动的具体过程。

3.Start 启动p2p网络

先来看一下大概的流程图:
(黄色方框表示调用了外部包,具体实现在黄色方框的go文件里。)

启动服务的大致流程
Start方法执行了三个主要的步骤:

Start方法也就是做了启动后的p2p网络会做的三件事情,其中节点发现发起TCP请求都涉及到了别的目录或go文件,所以放在下次介绍。接下来就是监听TCP连接的部分。

4.监听TCP连接的过程

分为两个部分:一是开启监听;二是监听循环。

startListening 开启监听

开启监听的过程比较简单,直接看代码。

func (srv *Server) startListening() error {
    // 创建监听用的 listener
    listener, err := net.Listen("tcp", srv.ListenAddr)
    if err != nil {
        return err
    }
    // 更新listener的地址,Addr返回的是listener的网络地址
    laddr := listener.Addr().(*net.TCPAddr)
    srv.ListenAddr = laddr.String()
    srv.listener = listener
    // 开始监听循环
    srv.loopWG.Add(1)
    go srv.listenLoop()
    // 如果配置了NAT,则映射TCP监听端口。
    if !laddr.IP.IsLoopback() && srv.NAT != nil {
        srv.loopWG.Add(1)
        go func() {
            nat.Map(srv.NAT, srv.quit, "tcp", laddr.Port, laddr.Port, "ethereum p2p")
            srv.loopWG.Done()
        }()
    }
    return nil
}
listenLoop 监听循环

监听循环有两个主要过程,如下图,左半图是循环的接收接入的TCP连接;右半图是在符合要求的连接之上,建立加密的通道,即使用rlpx协议。


监听循环以及加密通道建立
SetupConn 建立加密通道

5.总结

上一篇 下一篇

猜你喜欢

热点阅读