网络通信与区块链

undefinedGo网络与协议

网络通信与区块链 - 图1

TCP/IP 协议族:

  • ARP: Address Resolution Protocol, 正向地址解析协议。通过已知的IP,寻找对应的主机MAC地址。
  • RARP:是反响的地址转换协议,通过MAC地址确定IP地址。
  • IP:Internet Protocol,是因特网互联协议
  • ICMP:Internet Control Message Protocol,是Internet控制报文协议,它是TCP/IP协议的一个子协议,用于在IP主机、路由器之间传递控制消息。

    eg: ping 127.0.0.1 就是用到了ICMP协议

  • IGMP:Internet Group Management Protocol,是Internet组管理协议,它是因特网协议家族中的一个组播协议,该协议运行在主机和组播路由器之间。
  • TCP:Transmission Control Protocol,传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。主要用于 文件传输
  • UDP:User Datagram Protocol,是OSI参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。主要用于 聊天
  • FTP
  • Telnet
  • TFTP
  • NFS

网络通信与区块链 - 图2

通信的拆包与组包:

网络通信与区块链 - 图3

undefinedSocket编程

TCP的 C/S架构:

cs模型:客户端和服务器

客户端 ===》 客户

1)主动请求服务

服务器 ===》 客服

1)被动提供服务

网络通信与区块链 - 图4

undefinedGo网络通信编程

undefined服务器端

网络通信与区块链 - 图5

在区块链中,每一个节点既是服务器,也是客户端。

首先服务器在当前节点开启监听,protocol为tcp。在函数startserver退出后,关闭l服务器监听器ln句柄。

同时作为客户端,给中心节点发送version命令,请求区块版本(高度)检查和同步。

接下来进入无限循环,服务器监听器阻塞,等待客户端连接,并通过并发模式,接收来自客户端的连接请求,该并发任务协程会被放到服务器堆栈。该协程的名称是handleConnection。

undefined客户端

网络通信与区块链 - 图6

客户端通过方法net.Dial连接到服务器。在本函数执行完毕,将关闭与服务器的连接。

接下来将消息写入到conn通道。

undefined服务器端

网络通信与区块链 - 图7

服务器端接收到客户端的连接,阻塞解除,协程handleConnection被调用执行。

在handleConnection中,首先通过ioutil读取conn上的所有数据,然后解析命令。注意命令为12个字节(commandLength),request则是command+payload构成,payload在各个具体命令的handle中进行解析。

接下来,根据command,转到相应的处理函数中进行处理。

网络通信与区块链 - 图8

最后关闭通信连接。

undefined区块链的服务器和客户端

1、区块链是P2P网络,因此加入区块链的每一个节点,既是服务器,也是客户端。

所以,一般在sendData时候,都会将发送者的addr作为payload的一部分,发送给对方。

2、P2P通信,是点对点的强通信方式,多次请求-回答完成交互,从发送“麻烦告诉我你版本是什么”开始,发现本地版本比对方低,于是接着发送“麻烦告诉我你有什么”,对方将回复区块或交易的概要(哈希列表),再紧接着向对方要具体的数据(如某个区块或者某个交易)。

3、由于是P2P通信,所以每次请求-回答的数据都很小:在区块链中,每次请求只会请求一个区块的数据或者一个交易的数据,这将最大限度保证通信的可靠性。

undefinedMultiaddress

多地址(通常缩写为multiaddr)是一种约定,用于将多层寻址信息编码为单个“面向未来”的路径结构。

例如:/ip4/127.0.0.1/udp/1234对两个协议及其基本寻址信息进行编码。 /ip4/127.0.0.1通知我们,我们需要IPv4协议的127.0.0.1回送地址,而/ udp / 1234告诉我们,我们希望将UDP数据包发送到端口1234。

可以组成多地址来描述地址的多个“层”。

例如,multiaddr/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N唯一标识我的本地 IPFS 节点, 使用 libp2p的注册的协议ID/p2p/和我的IPFS节点公钥的multihash

undefinedMultiaddr简介:

Multiaddr aims to make network addresses future-proof, composable, and efficient.

Current addressing schemes have a number of problems.

  • They hinder protocol migrations and interoperability between protocols.
  • They don't compose well. There are plenty of X-over-Y constructions, but only few of them can be addressed in a classic URI/URL or host:port scheme.
  • They don't multiplex: they address ports, not processes.
  • They're implicit, in that they presume out-of-band values and context.
  • They don't have efficient machine-readable representations.

Multiaddr solves these problems by modelling network addresses as arbitrary encapsulations of protocols.

  • Multiaddrs support addresses for any network protocol.
  • Multiaddrs are self-describing.
  • Multiaddrs conform to a simple syntax, making them trivial to parse and construct.
  • Multiaddrs have human-readable and efficient machine-readable representations.
  • Multiaddrs encapsulate well, allowing trivial wrapping and unwrapping of encapsulation layers.

    Multiaddr was originallythought up by @jbenet.

    翻译如下:

    Multiaddr的目标是使网络地址可适应未来需求,可组合且高效。

    当前的寻址方案具有许多问题。

  • 它们阻碍协议迁移和协议之间的互操作性。
  • 他们表现不佳。有很多X-over-Y构造,但是只有少数可以用经典的URI / URL或host:port方案进行寻址。
  • 它们不复用:它们寻址端口,而不是进程。
  • 它们是隐式的,因为它们假定带外值和上下文。
  • 它们没有有效的机器可读表示。

Multiaddr通过将网络地址建模为协议的任意封装来解决这些问题。

  • Multiaddr支持任何网络协议的地址。
  • Multiaddr是自我描述的。
  • Multiaddr遵循简单的语法,使其易于解析和构造。
  • Multiaddr具有人类可读和有效的机器可读表示形式。
  • Multiaddr可以很好地封装,从而可以轻松封装和解开封装层。

    Multiaddr最初是由@jbenet想到的。

undefined以太坊的KAD协议

以太坊Kad网络中节点间通信基于UDP,主要由以下几个命令构成,若两个节点间PING-PONG握手通过,则认为相应节点在线。

网络通信与区块链 - 图9

undefined以太坊的邻居节点

C++版本以太坊源码中,NodeTable是以太坊 P2P网络的关键类,所有与邻居节点相关的数据和方法均由NodeTable类实现。

网络通信与区块链 - 图10

网络通信与区块链 - 图11

网络通信与区块链 - 图12

undefined邻居节点发现方法

邻居节点是指加入到K桶,并通过PING-PONG握手的节点。

网络通信与区块链 - 图13

邻居节点发现流程说明:

  • 系统第一次启动随机生成本机节点NodeId,记为LocalId,生成后将固定不变,本地节点记为local-eth。
  • 系统读取公共节点信息,ping-pong握手完成后,将其写入K桶。
  • 系统每隔7200ms刷新一次K桶。
  • 刷新K桶流程如下:

    a. 随机生成目标节点Id,记为TargetId,从1开始记录发现次数和刷新时间

    b. 计算TargetId与LocalId的距离,记为Dlt

    c. K桶中节点的NodeId记为KadId,计算KadId与TargetId的距离,记为Dkt

    d. 找出K桶中Dlt大于Dkt的节点,记为k桶节点,向k桶节点发送FindNODE命令,FindNODE命令包含TargetId

    e. K桶节点收到FindNODE命令后,同样执行b-d的过程,将从K桶中找到的节点使用Neighbours命令发回给本机节点。

    f. 本机节点收到Neighbours后,将收到的节点写入到K桶中。

    g. 若搜索次数不超过8次,刷新时间不超过600ms,则返回到b步骤循环执行。

undefined邻居节点网络拓扑及刷新机制

网络通信与区块链 - 图14

1 TargetId为随机生成的虚拟节点ID。

2 以太坊Kad网络与传统Kad网络的区别:

  • 以太坊节点在发现邻居节点的8次循环中,所查找的节点均在距离上向随机生成的TargetId收敛。
  • 传统Kad网络发现节点时,在距离上向节点本身收敛。