网络通信与区块链
undefinedGo网络与协议

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

通信的拆包与组包:

undefinedSocket编程
TCP的 C/S架构:
cs模型:客户端和服务器
客户端 ===》 客户
1)主动请求服务
服务器 ===》 客服
1)被动提供服务

undefinedGo网络通信编程
undefined服务器端

在区块链中,每一个节点既是服务器,也是客户端。
首先服务器在当前节点开启监听,protocol为tcp。在函数startserver退出后,关闭l服务器监听器ln句柄。
同时作为客户端,给中心节点发送version命令,请求区块版本(高度)检查和同步。
接下来进入无限循环,服务器监听器阻塞,等待客户端连接,并通过并发模式,接收来自客户端的连接请求,该并发任务协程会被放到服务器堆栈。该协程的名称是handleConnection。
undefined客户端

客户端通过方法net.Dial连接到服务器。在本函数执行完毕,将关闭与服务器的连接。
接下来将消息写入到conn通道。
undefined服务器端

服务器端接收到客户端的连接,阻塞解除,协程handleConnection被调用执行。
在handleConnection中,首先通过ioutil读取conn上的所有数据,然后解析命令。注意命令为12个字节(commandLength),request则是command+payload构成,payload在各个具体命令的handle中进行解析。
接下来,根据command,转到相应的处理函数中进行处理。

最后关闭通信连接。
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握手通过,则认为相应节点在线。

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



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

邻居节点发现流程说明:
- 系统第一次启动随机生成本机节点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邻居节点网络拓扑及刷新机制

1 TargetId为随机生成的虚拟节点ID。
2 以太坊Kad网络与传统Kad网络的区别:
- 以太坊节点在发现邻居节点的8次循环中,所查找的节点均在距离上向随机生成的TargetId收敛。
- 传统Kad网络发现节点时,在距离上向节点本身收敛。
