最近看了幾天的bitcoin的代碼于个,主要從網(wǎng)絡通信部分著手開始看的,對于一個三年多沒有寫過C++代碼的人來說暮顺,看其中的消息序列化反序列化代碼厅篓,只有一句臥艸感嘆,遂拾起多年未寫過的C++捶码,來寫點東西羽氮。
既然是看到了比特幣的P2P網(wǎng)絡,何不把這個網(wǎng)絡上的IP全部搞下來宙项,看看這些IP都分布在哪里乏苦,于是查看了下比特幣的網(wǎng)絡通信協(xié)議:兩個節(jié)點建立連接后,發(fā)起連接者發(fā)送version
命令尤筐,接受者響應verack
命令并發(fā)送version
命令,發(fā)起者響應verack
命令洞就,如下圖:
如果把verack
和version
畫在一起盆繁,就和TCP的三步握手一樣了。交換完這幾個協(xié)議命令之后旬蟋,兩個節(jié)點的連接就完全建立好了油昂,可以發(fā)送其他的一些協(xié)議命令了。看了文檔冕碟,沒有主動獲取對端相鄰節(jié)點的協(xié)議命令拦惋,只有一個addr
命令來主動告知對端與本節(jié)點相連的節(jié)點IP。
先寫個demo再說安寺,很簡單厕妖,從DNS seed獲取IP節(jié)點,建立連接挑庶,處理完握手之后不發(fā)送任何信息言秸,只接受消息,打印出接收到的命令迎捺,在一大串的命令之后举畸,收到了期盼的addr
命令,bingo!
心里大致有了一個流程圖凳枝,從DNS seed中獲取IP地址放入IP種子集合中抄沮,創(chuàng)建一個kqueue
(linux上是epoll
),不斷從IP種子集合中拿出一些IP岖瑰,創(chuàng)建TCP連接叛买,并開始監(jiān)聽讀寫事件,只要收到addr
協(xié)議命令后锭环,就從消息中取出IP地址放入IP種子集合中聪全。
真是說起來容易,做起來難辅辩,而且還三年多沒寫過C++了难礼,最后總算是能夠穩(wěn)定的跑起來了。進過四天的連續(xù)執(zhí)行玫锋,已經(jīng)獲取到了7.6W+個IP地址:
用tornado
寫了個web服務蛾茉,通過ip獲取地理位置信息,并做了點可視化:
我大天朝果然牛批撩鹿!占比25%左右谦炬!
還可以查看其它國家的具體分布,代碼已經(jīng)放在全球最大男性交友網(wǎng)站了节沦,https://github.com/lt90s/BitcoinNetwork键思,求星星~~~