一.前言
P2P,即英文Peer-to-Peer的縮寫,中譯爲對等互聯或點對點技術。講到P2P,人們就會想起Napster,Napster讓人們認識到了P2P技術的威力,P2P技術也就經過Napster進入了大多數用戶的視野,Napster的音樂文件交換功能是P2P的一個主要應用。P2P技術可讓用戶能夠直接鏈接到其餘用戶的計算機,進行文件共享與交換。同時P2P在深度搜索、分佈計算、協同工做等方面也大有用途。
簡單地說,P2P就是一種用於不一樣PC用戶之間,不通過中繼設備直接交換數據或服務的技術,它容許Internet用戶直接使用對方的文件。每一個人能夠直接鏈接到其餘用戶的計算機,並進行文件的交換,而不須要鏈接到服務器上再進行瀏覽與下載。由於消除了中間環節,P2P技術使得網絡上的溝通變得更容易、更直接。P2P改變了Internet如今的以大網站爲中心的狀態、重返"非中心化",並把權力交還給用戶。從某種意義上講,P2P體現了Internet的本質。在網絡還沒有發展成爲如今的Web以前,網民就是利用所謂的"佈告板"等渠道彼此直接交換信息和文件。
目前Internet的存儲模式是"內容位於中心",而P2P技術的運用將使Internet上的內容向邊緣移動。這將帶來如下改變:首先,客戶再也不須要將文件上傳到服務器,而只須要使用P2P與其餘計算機進行共享;其次,使用P2P技術的計算機不須要固定的IP地址和永久的Internet鏈接,這使得佔有極大比例的撥號上網用戶也能夠享受P2P帶來的變革。
理解P2P技術方面的最好方法是仔細觀察並理解一個實際的P2P應用程序。C#做爲微軟.Net戰略的重要棋子,對網絡編程提供了很好的支持和優化。本文就經過一個程序,向你們介紹一下C#下的P2P編程的方法和實現機理。本文的這個程序雖然不是頗有用,但卻很直觀地給出了P2P(點對點)編程以及套接口編程的一些基本知識和概念。它是創建在TcpListener以及TcpClient這兩個類基礎上的,除外還有相應的輸入和輸出控制。實現的原理也比較簡單,可是用到了P2P技術重返"非中心化"的基本原則。簡言之,用這個程序能夠在網絡中發送、接受信息,任何一臺計算機既能夠做爲服務器端,又能夠做爲客戶端。程序共用到了四個類:一個Listener類(用來監聽新的鏈接)、一個Sender類(用來發送信息)、一個Inputhandler類(用來控制輸入)、一個Initialize類(用來完成初始化工做)。下面,我先給你們介紹一下這四個類,最後再給出程序的具體實現方法。
二.基本類介紹
1.Listener類:
Listener類是用來監聽新的鏈接。當它的一個對象被創建並開啓後,該對象就開始不斷監聽來自網絡中的鏈接請求。一旦有了一個鏈接請求,該對象就設法創建鏈接並取得它的字節流進而轉化成字符串顯示在控制檯中。當一個鏈接結束後,該對象就繼續進行監聽來自網絡中的鏈接請求。
代碼以及註釋以下:
對Listen()函數的補充說明:
這個函數是Listener類的核心部分。該函數首先被構造函數調用。只要布爾值listenerRun爲true,咱們就能夠在端口5656建立並開始一個Tcp監聽對象TcpListener進行監聽網絡中的鏈接請求,而一旦listenerRun被置爲false,則表示程序結束了。在循環體內部,咱們先接受一個鏈接,用s.RemoteEndPoint得到它的IP地址並得到其字節流。根據得到的字節流,咱們用UTF8編碼將它轉化爲字符串。最後,咱們就在控制檯中顯示得到的字符串。
對於catch語句,第一個塊捕獲一個可能由防火牆引發的例外。由於對於防火牆而言,它可能認爲這是一個特洛依***或是儒蟲病毒什麼的,因此就會拒絕經過。解決辦法就是從新配置防火牆。第二個塊用於捕獲通常的例外,好比當咱們調用了stop()函數後,咱們銷燬了TcpListener對象,那就天然不可能再進行監聽了。
2.Sender類:
Sender類就一個函數,因此是至關簡單的。
代碼以及註釋以下:
對Send()函數的補充說明:
Send(string[] aInput)函數將一個數組做爲參數。數組的第一個元素Send(aInput[0])必須包含"send"這個字,不然Sender對象不會被建立(更多內容在InputHandler類中);第二個元素包含了目標計算機的IP地址;剩下的就是要發送的內容信息了。
在try塊中,咱們根據遠程計算機的IP地址在端口5656(要確保端口號統一)建立了一個TcpClient對象。而後,咱們創建一個NetworkStream和一個StremWriter對象來發送咱們的信息。在catch塊中,咱們用它來捕獲通常的例外,好比遠程計算機拒絕鏈接請求、網絡不通什麼的。
3.InputHandler類:
InputHandler類主要用來控制用戶輸入。
代碼以及註釋以下:
對InputHandler類的補充說明:
該類中有一個靜態的Listener對象li,一旦計算機運行此程序並執行"start"操做,該計算機就能夠成爲網絡中的服務器來監聽其餘計算機的鏈接請求。而該類的核心部分是一個switch case語句系列,經過不一樣的操做,咱們可使計算機扮演不一樣的角色:"send"操做代表該計算機相對目的計算機而言成了客戶端;而"start"操做就將計算機自身置爲服務器端,這正體現了P2P的既是服務器端又是客戶端的"非中心化"的原則;同時程序也提供了一些其餘的輔助操做。
4.Initialize類:
Initialize類進行程序的初始化工做,它新建了一個InputHandler對象,只要該對象的布爾值appRun爲true,就一直運行之,直到該值爲false,程序退出。
代碼以及註釋以下:
到此爲止,四個類已經介紹完畢,我想你們也早已等不及了吧,下面就簡單給你們介紹一下具體實現程序的方法。
三.實現方法
首先,打開Visual Studio.Net,新建一個名爲P2Ptest的控制檯應用程序的Visual C#項目,圖示以下:
圖1
其次,將以上四個類分別保存爲四個文件:listener.cs,sender.cs,inputHandler.cs,initialize.cs。而後將這四個文件添加到當前的工程中,同時把原有的主文件刪除便可(由於在initialize.cs中已經有主函數了)。
最後,按Ctrl+F5便可執行程序了。
爲了進行測試,咱們須要打開兩個P2Ptest程序,一個做爲服務器端,另外一個做爲客戶端。服務器端的圖示以下(此時已經開始監聽了):
圖2
客戶端的圖示以下(輸入命令行:send 10.85.7.79 Hello,I'm Pitt.Can you hear me?):
圖3
再看服務器端的狀況,圖示以下: