# Go網絡與協議

**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

**通信的拆包與組包:**

# Socket編程
TCP的 C/S架構:
**cs模型:客戶端和服務器**
客戶端 ===》 客戶
1)主動請求服務
服務器 ===》 客服
1)被動提供服務

# Go網絡通信編程
## 服務器端

在區塊鏈中,每一個節點既是服務器,也是客戶端。
首先服務器在當前節點開啟監聽,protocol為tcp。在函數startserver退出后,關閉l服務器監聽器ln句柄。
同時作為客戶端,給中心節點發送version命令,請求區塊版本(高度)檢查和同步。
接下來進入無限循環,服務器監聽器阻塞,等待客戶端連接,并通過并發模式,接收來自客戶端的連接請求,該并發任務協程會被放到服務器堆棧。該協程的名稱是handleConnection。
## 客戶端

客戶端通過方法net.Dial連接到服務器。在本函數執行完畢,將關閉與服務器的連接。
接下來將消息寫入到conn通道。
## 服務器端

服務器端接收到客戶端的連接,阻塞解除,協程handleConnection被調用執行。
在handleConnection中,首先通過ioutil讀取conn上的所有數據,然后解析命令。注意命令為12個字節(commandLength),request則是command+payload構成,payload在各個具體命令的handle中進行解析。
接下來,根據command,轉到相應的處理函數中進行處理。

最后關閉通信連接。
# 區塊鏈的服務器和客戶端
1、區塊鏈是P2P網絡,因此加入區塊鏈的每一個節點,既是服務器,也是客戶端。
所以,一般在sendData時候,都會將發送者的addr作為payload的一部分,發送給對方。
2、P2P通信,是點對點的強通信方式,多次請求-回答完成交互,從發送“麻煩告訴我你版本是什么”開始,發現本地版本比對方低,于是接著發送“麻煩告訴我你有什么”,對方將回復區塊或交易的概要(哈希列表),再緊接著向對方要具體的數據(如某個區塊或者某個交易)。
3、由于是P2P通信,所以每次請求-回答的數據都很小:在區塊鏈中,每次請求只會請求一個區塊的數據或者一個交易的數據,這將最大限度保證通信的可靠性。
# Multiaddress
多地址(通常縮寫為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](https://github.com/multiformats/multiaddr/blob/master/protocols.csv)`/p2p/`和我的IPFS節點公鑰的[multihash](https://docs.libp2p.io/reference/glossary/#multihash)。
## Multiaddr簡介:
Multiaddr aims to make network addresses future-proof, composable, and efficient.
Current addressing schemes have a number of problems.
1. They hinder protocol migrations and interoperability between protocols.
2. 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.
3. They don't multiplex: they address ports, not processes.
4. They're implicit, in that they presume out-of-band values and context.
5. 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 originally[thought up by @jbenet](https://github.com/jbenet/random-ideas/issues/11).
翻譯如下:
Multiaddr的目標是使網絡地址可適應未來需求,可組合且高效。
當前的尋址方案具有許多問題。
1. 它們阻礙協議遷移和協議之間的互操作性。
2. 他們表現不佳。有很多X-over-Y構造,但是只有少數可以用經典的URI / URL或host:port方案進行尋址。
3. 它們不復用:它們尋址端口,而不是進程。
4. 它們是隱式的,因為它們假定帶外值和上下文。
5. 它們沒有有效的機器可讀表示。
Multiaddr通過將網絡地址建模為協議的任意封裝來解決這些問題。
1. Multiaddr支持任何網絡協議的地址。
2. Multiaddr是自我描述的。
3. Multiaddr遵循簡單的語法,使其易于解析和構造。
4. Multiaddr具有人類可讀和有效的機器可讀表示形式。
5. Multiaddr可以很好地封裝,從而可以輕松封裝和解開封裝層。
Multiaddr最初是由[@jbenet](https://github.com/jbenet/random-ideas/issues/11)想到的。
# 以太坊的KAD協議
以太坊Kad網絡中節點間通信基于UDP,主要由以下幾個命令構成,若兩個節點間PING-PONG握手通過,則認為相應節點在線。

# 以太坊的鄰居節點
C++版本以太坊源碼中,NodeTable是以太坊?P2P網絡的關鍵類,所有與鄰居節點相關的數據和方法均由NodeTable類實現。



## 鄰居節點發現方法
?鄰居節點是指加入到K桶,并通過PING-PONG握手的節點。

鄰居節點發現流程說明:
1. 系統第一次啟動隨機生成本機節點NodeId,記為LocalId,生成后將固定不變,本地節點記為local-eth。
2. 系統讀取公共節點信息,ping-pong握手完成后,將其寫入K桶。
3. 系統每隔7200ms刷新一次K桶。
4. 刷新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步驟循環執行。
## 鄰居節點網絡拓撲及刷新機制

1 TargetId為隨機生成的虛擬節點ID。
2?以太坊Kad網絡與傳統Kad網絡的區別:
1. 以太坊節點在發現鄰居節點的8次循環中,所查找的節點均在距離上向隨機生成的TargetId收斂。
2. 傳統Kad網絡發現節點時,在距離上向節點本身收斂。
- 重要更新說明
- linechain發布
- linechain新版設計
- 引言一
- 引言二
- 引言三
- vs-code設置及開發環境設置
- BoltDB數據庫應用
- 關于Go語言、VS-code的一些Tips
- 區塊鏈的架構
- 網絡通信與區塊鏈
- 單元測試
- 比特幣腳本語言
- 關于區塊鏈的一些概念
- 區塊鏈組件
- 區塊鏈第一版:基本原型
- 區塊鏈第二版:增加工作量證明
- 區塊鏈第三版:持久化
- 區塊鏈第四版:交易
- 區塊鏈第五版:實現錢包
- 區塊鏈第六版:實現UTXO集
- 區塊鏈第七版:網絡
- 階段小結
- 區塊鏈第八版:P2P
- P2P網絡架構
- 區塊鏈網絡層
- P2P區塊鏈最簡體驗
- libp2p建立P2P網絡的關鍵概念
- 區塊鏈結構層設計與實現
- 用戶交互層設計與實現
- 網絡層設計與實現
- 建立節點發現機制
- 向區塊鏈網絡請求區塊信息
- 向區塊鏈網絡發布消息
- 運行區塊鏈
- LineChain
- 系統運行流程
- Multihash
- 區塊鏈網絡的節點發現機制深入探討
- DHT
- Bootstrap
- 連接到所有引導節點
- Advertise
- 搜索其它peers
- 連接到搜到的其它peers
- 區塊鏈網絡的消息訂發布-訂閱機制深入探討
- LineChain:適用于智能合約編程的腳本語言支持
- LineChain:解決分叉問題
- LineChain:多重簽名
- libp2p升級到v0.22版本
- 以太坊基礎
- 重溫以太坊的樹結構
- 世界狀態樹
- (智能合約)賬戶存儲樹
- 交易樹
- 交易收據樹
- 小結
- 以太坊的存儲結構
- 以太坊狀態數據庫
- MPT
- 以太坊POW共識算法
- 智能合約存儲
- Polygon Edge
- block結構
- transaction數據結構
- 數據結構小結
- 關于本區塊鏈的一些說明
- UML工具-PlantUML
- libp2p介紹
- JSON-RPC
- docker制作:啟動多個應用系統
- Dockerfile
- docker-entrypoint.sh
- supervisord.conf
- docker run
- nginx.conf
- docker基礎操作整理
- jupyter計算交互環境
- git技巧一
- git技巧二
- 使用github項目的最佳實踐
- windows下package管理工具