首先,程序運行後,用戶得先按下“開始監聽”按鈕,按鈕相應事件後,程序就進入了監聽狀態,狀態欄有相應的顯示。這樣,本機就相當於“服務器/客戶機”模式中的服務器了,其他計算機可以連接到本機並向本機發送消息。其他計算機通過該程序連接到本機是通過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能取得輝煌的發展。