UDP數據傳輸實例


下面通過一個例子,對UdpClient類的用法及它的一些方法進行說明。在UDP模式下,不存在明顯的服務器與客戶端之分,所以在這里用A端和B端代替。本例要實現的功能是從A端到B端的點對點通信。打開VS2008,在D:C#ch17目錄下建立名為P2PTest的Windows應用程序。打開工程,為當前窗體添加如表17-9所示控件。

  表17-9 添加控件列表

控件名 Name Text
Label Label1 對方IP:
TextBox tbIP  
TextBox tbMsg  
Button btnSend 發送
ListBox lbInfo  
GroupBox gbSend 發送窗口
GroupBox gbReceive 接收窗口
Button btnClear 清空

  本例是利用8888端口進行局域網內部的點對點通信,只要確認對方IP,就能相互發送信息。代碼的添加主要分為以下步驟。

  (1)首先是對幾個命名空間的引用,包括System.Net、System.Net.Sockets和System.Threading。然后定義如下三個全局變量。

雙擊代碼全選
1
2
3
4
5
private UdpClient uc;
  
private IPEndPoint iep;
  
private Thread th;

 

  其中UdpClient是本例的核心成員,主要通過它的相關方法進行數據的收發。

  (2)本例使用8888端口進行通信,所以應該在當前窗體構造函數Form1()內,用該端口實例化UdpClient。

雙擊代碼全選
1
2
3
4
5
6
7
8
9
10
11
public Form1()
  
    {
  
      InitializeComponent();
  
CheckForIllegalCrossThreadCalls = false;
  
      uc = new UdpClient(8888);
  
    }

 

  CheckForIllegalCrossThreadCalls主要是解決線程間的控件操作問題,通過將其屬性設置為fasle,可以禁用對操作控件的線程是否為創建該窗體的線程的檢測,阻止該異常的發生。這種問題在第16章中也遇到過,當時是采用的委托的方法進行解決。

  (3)雙擊“發送”按鈕,添加如下代碼。

雙擊代碼全選
1
2
3
4
5
6
7
8
9
10
11
12
13
iep = new IPEndPoint(IPAddress.Parse(tbIP.Text), 8888);
  
th = new Thread(new ThreadStart(listen));
  
th.IsBackground = true;                 //設置在后台運行
  
th.Start();                        //啟動線程
  
string temp = tbMsg.Text;
  
byte[] b = Encoding.UTF8.GetBytes(temp);  //對發送的數據的進行UTF8格式的編碼 
  
uc.Send(b, b.Length,iep);               //發送數據

 

  其中listen()方法用於監聽對方發送過來的消息,實現代碼如下。

雙擊代碼全選
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void listen()
  
{
  
  while (true)
  
  {
  
    string text = Encoding.UTF8.GetString(uc.Receive(ref iep));  //對發送的數據的進行UTF8格式的編碼
  
    lbInfo.Items.Add(text + "n");
  
  }
  
}

 

  (4)雙擊“清空”按鈕,添加如下代碼。

雙擊代碼全選
1
lbInfo.Items.Clear();

 

  (5)最后還需要進行一些資源釋放的操作。

雙擊代碼全選
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
protected override void Dispose(bool disposing)
  
{
  
  if (disposing && (components != null))
  
  {
  
    components.Dispose();
  
    th.Abort();                    //關閉線程
  
    uc.Close();                    //關閉UdpClient
  
  }
  
  base.Dispose(disposing);
  
}

 

  完成以上操作后,將該軟件放在兩台計算機之間進行測試。

  在測試過程中,發送的數據有時不能被對方收到。這是UDP本身的特性造成的,因為UDP是不可靠的傳輸協議,這也是基於UDP通信的缺點之一。

  在上面的例子中,收發數據用到了UdpClient類的幾種方法,如Send()和Receive(),下面對這些方法進行詳細說明。

  首先看發送數據用到的Send()方法,它具有以下重載形式。

雙擊代碼全選
1
2
3
4
5
public int Send(byte[] dgram,int bytes);
  
public int Send(byte[] dgram,int bytes,string hostname,int port);
  
public int Send(byte[] dgram,int bytes);

其中,dgram表示需要發送的數據,它必須滿足字節數組的格式;bytes表示該字節數組的長度;hostname和port指需要接收數據的主機名和端口號。

  接着是接收數據用到的Receive()方法,它沒有重載形式,聲明如下。

雙擊代碼全選
1
public byte[] Receive(ref IPEndPoint remoteEP);

 

  這里需要注意的是它的參數是引用類型,且remoteEP應該取發送方的IP和端口號。

  JoinMulticastGroup()方法能將UdpClient類添加到多路廣播組,它的用法如下所示。

雙擊代碼全選
1
2
3
4
5
public void JoinMulticastGroup(IPAddress multicastAddr);
  
public void JoinMulticastGroup(IPAddress multicastAddr,int timeToLive);
  
public void JoinMulticastGroup(int ifindex,IPAddress multicastAddr);

 

  multicastAddr和前面所提到的IPAddress的實例有了本質區別,它不再是單個主機的IP地址,而是一個廣播地址。如果將IP中標識主機的部分全置“1”,即表示該網絡的廣播地址。比如校園網常用的C類地址,只要將最后8位全部置“1”即可得到本地網絡中的廣播地址。它的優勢是能實現廣播的功能,比如從A端發出數據,在B、C、D、E端等都能同時接收,而不是像上個例子中必須指定接收方的IP。timeToLive是按路由器跳數測量的TTL。

  JoinMulticastGroup()的用法比較簡單,如下所示。

雙擊代碼全選
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System.Net;
  
using System.Net.Sockets;
  
……
  
UdpClient uc = new UdpClient();
  
IPAddress bcip =IPAddress.Parse("222.18.142.255"); //C類IP的廣播地址
  
try
  
{
  
  uc.JoinMulticastGroup(bcip,20);            //添加到多路組播
  
}
  
catch(Exception ex)
  
{
  
  Console.WriteLine(ex.Message);
  
}

 

  DropMulticastGroup()方法進行與JoinMulticastGroup()方法相反的操作,用法如下所示。

雙擊代碼全選
1
public void DropMulticastGroup (IPAddress multicastAddr);

 

  本節到目前為止,主要介紹了UdpClient類的用法,其實直接用Socket類也能完成同樣的功能。鑒於篇幅有限,就不再詳述。只是有一點需要指出,利用Socket連接創建基於UDP的通信時,它的實例化方法應與TCP進行區別,如下所示。

雙擊代碼全選
1
Socket s = new Socket(AddressFamily.InterNetwork,SocketType.Dgram, ProtocolType.Udp);

 

  后面兩個參數發生了變化,SocketType的類型選擇Dgram,表示數據傳輸是以數據報的形式而非流;協議類型需要選擇Udp。

  UDP與TCP相比,在某些方面較有優勢。比如它的實時性比TCP要好,它不需握手、差錯檢驗和流的控制;它產生的負載很少等。它的缺點是數據傳輸不可靠。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM