首先,程式運行後,使用者得先按下“開始監聽”按鈕,按鈕相應事件後,程式就進入了監聽狀態,狀態列有相應的顯示。這樣,本機就相當於“伺服器/客戶機”模式中的伺服器了,其他電腦可以串連到本機並向本機發送訊息。其他電腦通過該程式串連到本機是通過IP地址來實現的,C#對網路編程有很好的支援,所以程式員的工作量是比較小的。如此,一台電腦可以向另一台發送訊息了。然而,這是個P2P程式,所以只要另一台電腦的使用者也按下"開始監聽"按鈕,那台電腦也成了這台電腦的伺服器了。於是就實現了訊息互發功能,然而真正的伺服器是不存在的,每台電腦都是伺服器,每台電腦同時也是客戶機,這就體現了P2P技術的"非中心化"原則。
程式主要用到了一個Listen()函數和一個Send()函數。前者實現程式的監聽功能,函數實現如下:
private void Listen(){ try { tcpl = new TcpListener(5656); tcpl.Start(); statusBar1.Text = "正在監聽..."; while(listenerRun) { Socket s = tcpl.AcceptSocket(); Byte[] stream = new Byte[80]; int i=s.Receive(stream) ; string message = System.Text.Encoding.UTF8.GetString(stream); richTextBox1.AppendText(message); } } catch(System.Security.SecurityException) { MessageBox.Show("防火牆安全錯誤!","錯誤", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } catch(Exception) { statusBar1.Text = "已停止監聽!"; } } |
函數的主體是一個try-catch語句,try部分又是一個while迴圈,這表示只要使用者不按"停止監聽"按鈕,程式就會一直處於監聽狀態。監聽的連接埠是5656,這個連接埠是可以自己定義的,只要不跟常用的連接埠混淆就行了。一旦程式接收到遠端電腦的一條訊息,就將該訊息添加到訊息顯示框中(訊息顯示框就是那個RichTextBox控制項)。函數的catch部分是捕捉一些異常用的,如使用者之間設定了防火牆,就不能彼此通訊了,或是對方已經停止監聽了,那當然就不能向它發送訊息了。另一個函數Send()是實現程式發送訊息的功能的。函數實現如下:
private void Send() { try { string msg = "<"+textBox3.Text+">"+textBox2.Text; TcpClient tcpc = new TcpClient(textBox1.Text, 5656); NetworkStream tcpStream = tcpc.GetStream(); StreamWriter reqStreamW = new StreamWriter(tcpStream); reqStreamW.Write(msg); reqStreamW.Flush(); tcpStream.Close(); tcpc.Close(); richTextBox1.AppendText(msg); textBox2.Clear(); } catch(Exception) { statusBar1.Text = "目標電腦拒絕串連請求!"; } } |
該函數的主體部分也是一個try-catch語句,它先根據使用者的輸入,建立一個和遠端電腦的串連,注意其連接埠也為5656,而且必須是5656,這是為了和接收方連接埠保持一致,這樣對方才能收到這裡發送的訊息。接著,函數根據使用者在訊息輸入框中的內容以及使用者的暱稱向遠端電腦發送訊息。這樣,只要網路無故障、遠端電腦已經處於監聽狀態,它就能接收到這裡發送的訊息了。當然,這裡處於監聽狀態了,遠端電腦也可以自如地往這裡發訊息。函數的catch部分也是用於捕捉一些異常的。
同時還要注意的是,由於該程式用到了許多網路編程所需的對象以及輸入輸出對象,又運用了多線程編程機制,所以在程式的開始出得添加如下一些名字空間:
using System.IO; using System.Net.Sockets; using System.Threading; |
最後,程式中各個控制項的事件處理函數以及完整的代碼請參看文後附帶的原始碼包。程式啟動並執行圖示如下:
現在一個很基本的P2P運用程式以及完成,通過它,我們可以利用P2P技術的基本特性實現點對點通訊。通過這個程式,我相信大家對C#下的P2P編程應該有了大致的瞭解。對於這個程式,不足的一點是功能比較簡單,只可以發送、接受資訊,而且不能穿過防火牆進行通訊,讀者可以試著開發出功能更強P2P應用程式。
總結
最後,筆者希望能通過此文喚起大家對P2P技術的興趣。因為P2P身後所蘊藏著的無比的創造力使人們對未來互連網充滿了美好的憧憬,現在世界範圍的P2P應用熱潮也是一浪高過一浪。在可以預見的未來,隨著對P2P研究的進一步深入和關注P2P的群體逐漸增多,P2P必將進入一個飛速發展的新時期。然而國內的P2P起步得比較晚,所以更需要有大量的技術研究投入以及足夠的重視以贏得更好的發展。在此,筆者希望國內的P2P能取得輝煌的發展。