天天看點

[C# 網絡程式設計系列]專題八:P2P程式設計

引言:

前面的介紹專題中有朋友向我留言說介紹下關于P2P相關的内容的,首先本人對于C#網絡程式設計也不是什麼大牛,因為能力的關系,也隻能把自己的一些學習過程和自己的一些學習過程中的了解和大家分享下的,下面就進入正題——P2P(Peer to Peer)程式設計

一、P2P的介紹

首先,現在大家熟知的BT、電驢、迅雷、QQ、MSN和PPlive等都是基于P2P方式實作的軟體,并且對等聯網(Peer to Peer,P2P)将是網際網路的發展方向,是以對于P2P技術的了解顯得非常的重要,下面就來介紹下P2P架構:

在P2P技術之前,我們所有的網絡應用都采用C/S或者B/S架構來實作的,然而在之前C/S架構的應用程式中,用戶端軟體向伺服器送出請求,伺服器然後對用戶端請求做出響應,在這種情況下,如果用戶端越多,此時伺服器的壓力就越大。然而采用P2P技術實作的每台計算機既是用戶端,也是伺服器,他們的功能都是對等的。對于安裝了P2P軟體(如迅雷,QQ等)的計算機加入一個共同的P2P網絡,網絡中的節點之間可以直接進行資料傳輸和通信。

1.1 P2P架構和C/S架構的比較

C/S架構有下面的缺點(其實上面的簡單介紹中也講到過):

1. 伺服器負擔過重。當大量使用者通路C/S系統的伺服器時,伺服器常常會出現網絡堵塞等現象,這時候,我們可能會通過增加投資提高伺服器的硬體性能

2. 系統穩健性和伺服器關聯密切。指的是——如果伺服器出現了問題時,整個系統的運作将會癱瘓(感覺是面向對象中經常強調的原則——低耦合原則)

然而P2P具有下面的特點:

1.對等模式

P2P系統中的用戶端能夠同時扮演用戶端和伺服器的角色,使兩台計算機之間能夠不通過伺服器直接進行資訊分享(QQ中當好友線上的時候發資訊時,相信此時是不需要經過伺服器轉發的,隻有當給離線好友發送消息時,此時應該會先把消息發送到伺服器端存儲起來,當好友再次登入的時候,會和伺服器進行連接配接,伺服器會進行判斷是不是給這個使用者的資訊來決定是否轉發,QQ軟體的實作屬于混合型P2P結構的, 這個會在後面的P2P系統分類中介紹。)

注:括号中都是我個人的一些了解,如果有什麼說錯的地方請大家及時更正我,這樣我會及時的更新以免誤導大家,謝謝大家監督。

2. 網絡資源的分布式存儲

在C/S架構中,所有用戶端都直接從伺服器下載下傳所有資料資源,這樣勢必會加重伺服器的負擔,而P2P則改變了以伺服器為中心的狀态,使每個節點可以先從伺服器上個下載下傳一部分,然後再互相從對方或者其他節點下載下傳其餘部分。采用這種方式,當大量用戶端同時下載下傳時,就不會形成網絡堵塞現象了。

1.2 P2P系統的分類

使用P2P技術的系統分為兩類:(1)單純型P2P——沒有專用的伺服器。安裝了P2P軟體的各個計算機可以直接通信

              (2)混合型P2P——有專用的伺服器,此時的伺服器一般叫索引伺服器,此伺服器與C/S架構下的伺服器不同,在C/S架構下所有資源都存儲在伺服器中,所有傳遞的資訊都要經過伺服器,而在混合型P2P系統中的索引伺服器僅僅起到協調和擴充的功能,資源不是全部存儲在伺服器上,而是分布在各個電腦上,安裝了P2P軟體的電腦開始全部和索引伺服器連接配接,以便告知自己監聽的IP位址和端口号,然後再通過索引伺服器告訴其他與自己連接配接的電腦,每台計算機的連接配接和斷開都通過伺服器通知網絡上有聯系的計算機,這樣就減輕了每台計算機搜尋其他計算機的負擔,但是資訊的傳遞還是通過點對點的方式來完成(這裡可以以QQ為例,當我們電腦上安裝了QQ這類P2P軟體時,安裝了QQ這類軟體的計算機就會加入一個P2P網絡,并且登陸的時候都會與索引伺服器建立連接配接,通過連接配接來告訴伺服器自己的IP位址和端口号,當我們找一個好友聊天時,此時自己的計算機和好友的計算機都會與伺服器端口連接配接,但是要互相發送消息,自己的計算機必須知道好友計算機的IP位址和端口号才可以通信,這樣的工作正是通過索引伺服器來告知對方的--指的是告訴自己的計算機好友的計算機的IP位址和端口号,告訴好友的計算機自己的IP位址和端口号,這樣雙方就可以不通過伺服器直接通信了。)

1.3 主流P2P應用分類

P2P 網絡應用大緻可以分為三類—— 1. 檔案共享類,例如迅雷,BT等軟體都是檔案共享類的應用

                 2. 即時通信類,例如QQ,MSN等軟體都是屬于即時通信類

                 3. 多媒體傳輸類,例如線上視訊直播軟體,PPlive等軟體

從上面的分類可以看出,現在網絡上流行的軟體都采用了P2P技術來實作的, 但是它們的實作肯定不是單純的隻采用P2P技術來實作的, 而是采用多種技術來實作的, 在下一專題中将介紹利用TCP,UDP和P2P等技術來實作類似QQ的一個即時通信程式,希望通過此程式可以綜合前面專題介紹的内容以及幫助大家對QQ等軟體的實作原理有了解。

二、P2P的基本原理

在前面我們對P2P的一些知識進行的簡單的介紹, 通過前面的介紹相信大家對P2P的技術有了一定的了解,但是要自己開發一個P2P的應用當然必須了解P2P技術的實作原理的,下面就介紹下P2P實施的基本原理。

安裝了P2P軟體後,首先雙方要進行通信,必須能夠發現對方(指的就是知道對方的IP位址和端口号),一旦發現了對方後才可以進行通信,是以P2P應用程式一般分為發現、連接配接和通信3個階段。 發現階段負責動态定位通信方的網絡位置;連接配接階段負責在雙方建立網絡連接配接,通信階段負責在雙方之間傳輸資料。

2.1 發現階段

一台計算機要和另外一台計算機通信,必須知道對方的IP位址和監聽端口,否則就無法向對方發送消息。在之前的C/S架構中,伺服器的IP位址一般固定不變的,并且提供服務的計算機域名也一般不會改變,是以為了友善用戶端通路,一些Web伺服器在DNS(DNS其實就是域名和IP位址的一個映射)中進行了注冊,客戶機可以利用域名解析機制将伺服器域名解析為IP位址,然後在P2P應用中,各個對等節點(計算機或資源)可以随時加入和随時離開,并且對等節點的IP位址也不是固定的,是以不能采用DNS的機制來擷取P2P架構中的對等節點的資訊。

目前,在單純型P2P中,針對如何發現對等節點,各種P2P技術采用的協定和标準都不一樣,微軟在.net 支援對等名稱解析協定(Peer name Resolution Protocol, PNRP),該協定可以發現對等節點的資訊,通過無伺服器的解析功能将任何資源解析為一組IP位址和端口号,在後面的實作的簡單程式用的就是這個協定來完成發現階段的。

2.2 連接配接和通信階段

完成對等節點的發現後,接下來就可以根據需要,選擇TCP、UDP或者其他協定完成資料傳輸。如果選擇TCP,則需要先建立連接配接,再利用該連接配接傳輸資料,關于TCP的内容可以檢視我之前的專題;如果選擇UDP,則無須建立連接配接,直接在對等節點之間通信就可以了。

三、.net平台對P2P程式設計的支援

之前在發現階段也介紹了.Net平台對P2P程式設計的支援的,然後微軟幫我們已經封裝好了對PNRP協定的實作,這些類在System.Net.PeerToPeer命名空間裡(微軟現在很多東西都幫我們封裝了,這樣可以友善我們開發應用程式,感覺微軟的做的東西都是這樣,把程式的實作都幫我們做好了,我們開發程式的時候隻要關注業務邏輯就好了的, 這樣做當然有好處也有壞處的, 我覺得好處就是縮短軟體的開發周期,讓花更多的時間去實作軟體真真的業務邏輯方面的東西,不好的地方就是現在的程式員就不能叫程式員,是以園子裡面有很多人都稱碼農,這些我自己的觀點了)

3.1 對等名稱解析協定(PNRP)

PNRP可以完成對等名稱的注冊和解析(可以和DNS對比來了解)。

3.1.1 基本概念

第一個介紹的是對等名稱的概念,我們将每一個網絡資源(包括計算機,P2P應用程式、視訊、Mp3或其他文檔等資源)抽象為對等節點,對等節點名稱當然就是對等節點的名稱。對等節點名稱簡稱為對等名,分為安全的和不安全的兩種形式,不安全的名稱僅由文本字元串組成,任何人都可以注冊一個相同的不安全對等名稱;安全的由一個公鑰/私鑰(代表唯一)對支援,是以使用PNRP注冊時,不會受到欺騙,對等名稱的格式如下:

Authority.Classifier

Authority的值取決于該名稱的安全類型。對于不安全的類型,Authority為單字元“0”,而對于安全的對等名稱,Authority由40個十六機制字元組成

Classifier是使用者定義的用于标志對等節點的字元串,最大長度為150個Unicode字元。例如,對等名稱0.PeerNametest1就是一個不安全的對等名稱。

第二個概念就是雲(Cloud)的概念,安裝了相同P2P軟體的計算機會加入一個共同的P2P網絡中,才能互相識别各自擁有的資源并順利進行P2P通信。微軟PNPR協定将這個P2P網絡稱為“雲”。雲是指一組可以通過P2P網絡互相識别的對等節點及其上資源的集合。雲中的所有對等節點都可以解析注冊到該雲中的其他任何資源所在的位置(IP+Port),一個對等節點上的某個資源可以同時注冊到多個雲中。

PNPR目前使用了兩種雲——本地雲和全局雲。一個對等名稱若注冊到連結一本地雲,就意味着隻有同一本地網絡上的其他對等節點可以解析該名稱。而注冊到全局雲上的對等名稱則允許IPv6網際網路的任何對等節點解析。

注:全局雲是基于IPv6協定的,并不支援IPv4,如果不存在IPv6位址,則不會出現全局雲,也無法加入全局雲。由于現在網上絕大多數應用使用的仍然是IPv4的位址,是以我們通常的P2P程式設計還用不到全局雲,而隻能使用預設的本地雲。

3.1.2 名稱注冊

任何資源要被網絡上的其他計算機識别到,首先必須注冊進P2P網絡,名稱注冊就是将包含對等節點資訊的對等名稱釋出到雲中,以便其他對等節點解析。一個資源如果注冊到雲中後,就可以被雲中的其他對等節點解析和通路。

關于名稱注冊的具體内容,在後面的P2P的程式中也會使用的, 相信大家可以通過代碼來進一步了解名稱的注冊,這裡就先介紹到這裡的

3.1.3 名稱解析

名稱解析是指利用對等名稱擷取到雲中資源所在對等節點的IP位址和端口号的過程(和DNS解析原理一樣)。PNPR名稱解析僅能夠注冊到雲中的其他對等節點資源,而不能發現自身注冊的資源

PNPR協定沒有使用索引伺服器,是以為了完成解析,雲中的每個對等節點都存儲一些PNRP ID的緩存記錄。PNPR緩存中的都含有PNPR ID和應用程式的IP位址和端口号。名稱解析的步驟為——首先在本地計算機對等節點的緩存中查找目标資源,如果沒有,則在緩存中的臨近節點檢視,這樣循環下去,直到找到目标資源所在的對等節點位置。

3.2 PeerToPeer命名空間

上面主要介紹了PNPR協定的工作過程(相當于是理論部分了),下面就介紹下.net 為我們封裝好PNPR的類的使用。這裡就簡單指明幾個常用類的使用,并附上MSDN的連結,大家可以直接點連結進行檢視詳細内容,因為後面的P2P程式中也有具體的使用,是以這裡就不一一列出來了。

類名

MSDN連結

Peer類

<a href="http://msdn.microsoft.com/zh-cn/library/system.net.peertopeer.collaboration.peer.aspx">http://msdn.microsoft.com/zh-cn/library/system.net.peertopeer.collaboration.peer.aspx</a>

Cloud類

<a href="http://msdn.microsoft.com/zh-cn/library/system.net.peertopeer.cloud.aspx">http://msdn.microsoft.com/zh-cn/library/system.net.peertopeer.cloud.aspx</a>

PeerName類

<a href="http://msdn.microsoft.com/zh-cn/library/system.net.peertopeer.peername.aspx">http://msdn.microsoft.com/zh-cn/library/system.net.peertopeer.peername.aspx</a>

PeerNameRecord類

<a href="http://msdn.microsoft.com/zh-cn/library/system.net.peertopeer.peernamerecord.aspx">http://msdn.microsoft.com/zh-cn/library/system.net.peertopeer.peernamerecord.aspx</a>

PeerNameRegistration類

<a href="http://msdn.microsoft.com/zh-cn/library/system.net.peertopeer.peernameregistration_members(v=VS.90).aspx">http://msdn.microsoft.com/zh-cn/library/system.net.peertopeer.peernameregistration_members(v=VS.90).aspx</a>

PeerNameResolver類

<a href="http://msdn.microsoft.com/zh-cn/library/system.net.peertopeer.peernameresolver.aspx">http://msdn.microsoft.com/zh-cn/library/system.net.peertopeer.peernameresolver.aspx</a>

這些類基本上從類名都可以大緻知道他們的用途的,是以在這裡就沒有一一介紹的,隻是附上了MSDN的連結。

四、實作P2P應用程式

以上介紹了那麼多P2P的相關的知識,主要是為了實作一個自定義的P2P應用程式做準備的,這裡就簡單實作了資源發現的一個程式。

核心代碼:

對等名稱的注冊代碼:

名稱解析代碼(搜尋資源):

運作結果截圖:

為了示範資源發現的效果,是以同時開啟了本程式的3個程序來模拟網絡上對等的3個計算機節點,當在資源名中輸入資源後會在分享下清單中顯示出本地分享的資源,同時在P2P網絡上的其他計算機可以通過資源名稱搜尋該資源,将得到的資源名稱和釋出時間顯示在ListView控件中,下面是程式的運作結果:

五、總結

到這裡P2P程式設計的介紹就結束了, 本專題隻是簡單示範了一個資源發現的程式,資源發現是P2P的核心技術,正是因為P2P技術實作了網際網路範圍的資源發現,才使得它被廣泛應用,像我們經常用的下載下傳工具——迅雷,迅雷就是典型采用P2P技術的應用程式,當我們在迅雷頁面中輸入“愛情較高價的電梯大廈3”(相當于本專題中種子文本框填的資源名)然後點選搜尋後迅雷會自動啟動“狗狗搜尋”并顯示資源連結清單,當我們點選連接配接就可以進行下載下傳了。不過迅雷肯定不是使用微軟的PNPR,而是迅雷自主研發的與PNPR作用一樣的協定——都是完成解析網絡資源的位址的作用,當然,迅雷軟體中也采用了其他的一些技術,如搜尋引擎等。

希望本專題可以幫助大家對P2P技術有所了解,如果有任何的問題都可以通過留言的方式來一起讨論,在下一個專題中将介紹實作一個類似QQ的程式。

<a href="http://down.51cto.com/data/2361663" target="_blank">附件:http://down.51cto.com/data/2361663</a>

     本文轉自LearningHard 51CTO部落格,原文連結:http://blog.51cto.com/learninghard/1038678,如需轉載請自行聯系原作者

繼續閱讀