c# p2p 穿透(源碼加密)

http://blog.oraycn.com/ESFramework_Demo_P2P.aspxweb

 

測試,徹底OK!  我很喜歡這個。能夠源碼是加密的!我但願實現 web 版本的p2p視頻觀看,aehyok提出 用 SignalR 。要學習的東西不少啊。api

msdn 上面有p2p 的局域網實例代碼下載。服務器

 

ESFramework Demo -- P2P通訊Demo(附源碼)

      如今咱們將在ESFramework Demo -- 文件傳送Demo 的基礎上,使用ESPlus提供的第四個武器,爲其增長P2P通訊的功能。在閱讀本文以前,請務必先掌握ESFramework 開發手冊(04) -- 可靠的P2P 一文中介紹的P2P的基礎知識以及相關API的用法。網絡

      本Demo主要演示如下功能:框架

(1)建立基於TCP的P2P通道post

(2)建立基於UDP的P2P通道(內部使用可靠的UDP)性能

(3)使用P2P通道發送消息和傳送文件 學習

一.服務端

      在P2P打洞的過程當中,服務端會參與協助P2P通道的創建,整個過程是由ESFramework/ESPlus內部自動完成的,而這個過程對於框架使用者是透明的。P2P通道建立後,客戶端與客戶端之間的通訊就與服務器沒有任何關係了。因此咱們直接把上一個demo的服務端拿過來用,不須要作任何修改。 測試

二.客戶端

      客戶端主要使用IRapidPassiveEngine提供的P2PController來查詢和控制P2P通道的狀態。this

嘗試建立P2P通道    

      正如ESFramework 開發手冊(04) -- 可靠的P2P 一文中介紹的,並非全部的客戶端之間的P2P通道均可以建立成功,建立P2P通道是一個嘗試的過程,IP2PController的P2PConnectAsyn方法就是嘗試與目標用戶建立P2P通道。

      時機很重要。在什麼時候建立P2P通道了?通常而言,是在兩個客戶端須要高頻通訊以前,調用P2PConnectAsyn進行嘗試建立。

      在本Demo中,咱們是在每次打開與目標用戶的聊天窗口的時候,來嘗試建立P2P通道的。以下所示:

複製代碼
  void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (e.Button != System.Windows.Forms.MouseButtons.Left)
{
return;
}

ListViewHitTestInfo info = this.listView1.HitTest(e.Location);
if (info.Item != null)
{
//嘗試與目標用戶創建P2P通道
this.rapidPassiveEngine.P2PController.P2PConnectAsyn(info.Item.Text);
          ChatForm form = this.chatFormManager.GetForm(info.Item.Text);
          ......
      }
  }
複製代碼

      使用P2PConnectAsyn方法開始打洞時,若雙方位於同一局域網,通常會創建起基於TCP的P2P通道;若雙方位於不一樣的網絡,通常會創建起基於UDP的P2P的通道。若是與目標用戶之間已經存在可用的P2P通道,則P2PConnectAsyn將再也不作任何動做,而直接返回。

      爲了得到P2P通道建立成功或失敗以及後續P2P通道被關閉的通知,demo中咱們在MainForm的Initialize方法中預約了P2PController的P2PChannelOpened和P2PChannelClosed事件。

   //預約P2P Channel建立成功的事件
this.rapidPassiveEngine.P2PController.P2PChannelOpened += new CbGeneric<P2PChannelState>(P2PController_P2PChannelOpened);
//預約P2P Channel關閉時的事件
this.rapidPassiveEngine.P2PController.P2PChannelClosed += new CbGeneric<P2PChannelState>(P2PController_P2PChannelClosed);

      當P2P通道建立成功或被關閉時,本demo經過修改對應聊天窗口的Title文字來顯示這種狀態。好比,當P2P通道建立成功時,聊天窗口的Title顯示以下:

    

      一般,若是兩個客戶端位於同一個LAN,或者有一個客戶端直接位於Internet上,則它們之間的P2P通道是基於TCP的;不然,建立的P2P通道是基於UDP的。

      ChatForm提供了ShowP2PChannelState方法來顯示與聊天對象之間的P2P通道狀態。

複製代碼
        ///<summary>
/// 顯示P2P鏈接的狀態
///</summary>
public void ShowP2PChannelState(P2PChannelState state)
{
this.Text = (state != null) ? string.Format("正在與{0}對話中【{1}直連:{2}】...", this.friendID, state.ProtocolType, state.DestIPE) : string.Format("正在與{0}對話中...", this.friendID);
}
複製代碼

      請注意,當與目標用戶之間沒有P2P通道時,P2PController的GetP2PChannelState方法返回的是null。

觀察P2P通訊

      當P2P通道建立成功後,兩個用戶之間的後續通訊將通過P2P通道傳送,在本Demo中,表示後續的聊天消息以及文件傳送都將經過P2P通道進行。

      那麼,如何判斷消息是經過服務器中轉的,仍是通過P2P通道直接傳送的了?咱們經常使用的有兩個簡單的方法。

(1)觀察服務器的MainServerForm界面。      

     

      若是消息是通過服務器中轉的,那麼界面上顯示消息接收者用戶對應的「下載次數」、「上傳次數」、「最後一次下載時間」等都會跟着發生變化。就本例來講,每當你給對方發送一個聊天消息,若是是通過服務器中轉,那麼界面上顯示的對方的下載次數會增長1,本身的上傳次數也增長1,本身的最後一次上傳時間也會變化。而若是消息是經過P2P通道傳送的,這些數據就不會受影響。

(2)查看資源監視器

      若是是Win7的系統,任務管理器「性能」顯示中提供了「資源監視器」,能夠監控網絡的活動。使用它,咱們就能夠看到應用程序在和哪些機器進行通訊。以下圖所示:

     

      上面是咱們另外一個P2P應用demo的截圖,圖中59.175.145.163是服務器的IP,而咱們看到OMCS.ClientDemo.exe接收數據的主要流量來自於ZY-PC這臺電腦,這表示兩個客戶端之間的數據是通過P2P通道傳送的,沒有經過服務器中轉。之因此圖中顯示的客戶端與服務器之間還有微小的流量,那是由相似定時心跳消息等產生的。

      若是不是Win7系統,也能夠經過安裝網絡監控軟件(如NetLimiter)來查看這些信息。

三.源碼下載

 ESFramework.Demos.P2P 源碼

----------------------------------------------------------------------------------------------------------------------------------------------- 

 下載免費版本的ESFramework 以及 demo源碼  

Q Q:168757008

官網: www.oraycn.com
相關文章
相關標籤/搜索