C#中UDP(Socket)


復制代碼

 1 使用無連接的套接字,我們能夠在自我包含的數據包里發送消息,采用獨立的讀函數讀取消息,讀取的消息是使用獨立的發送函數發送的。但是UDP數據包不能保證可靠傳輸,存在許多的因素,比如網絡繁忙等等,都有可能阻止數據包到達指定的目的地。
 2    (1)UDP的簡單應用:
 3     由於UDP是一種無連接的協議。因此,為了使服務器應用能夠發送和接收UDP數據包,則需要做兩件事情:
 4     創建一個Socket對象;
 5     將創建的套接字對象與本地IPEndPoint進行綁定。
 6     完成上述步驟后,那么創建的套接字就能夠在IPEndPoint上接收流入的UDP數據包,或者將流出的UDP數據包發送到網絡中任意其他設備商。使用UDP進行通信時,不需要TCP連接。因為異地的主機之間沒有建立連接,所以UDP不能使用標准的Send()和Receive()t套接字方法,而是使用兩個其他的方法:SendTo()和ReceiveFrom()。
 7     SendTo()方法指定要發送的數據,和目標機器的IPEndPoint。該方法有多種不同的使用方法,可以根據具體的應用進行選擇,但是至少要指定數據包和目標機器。如下:
 8     SendTo(byte[] data,EndPoint Remote)
 9     ReceiveFrom()方法同SendTo()方法類似,但是使用EndPoint對象聲明的方式不一樣。利用ref修飾,傳遞的不是一個EndPoint對象,而是將參數傳遞給一個EndPoint對象。
10    (2)UDP服務器
11     UDP應用不是嚴格意義上的真正的服務器和客戶機,而是平等的關系,即沒有主與次的關系。為了簡便起見,仍然把下面的這個應用叫做UDP服務器。源代碼如下:
12 using System;
13 using System.Collections.Generic;
14 using System.Text;
15 using System.Net;
16 using System.Net.Sockets;
17 namespace SimpleUdpSrvr
18 {
19     class Program
20     {
21         static void Main(string[] args)
22         {
23             int recv;
24             byte[] data = new byte[1024];
25             IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);//定義一網絡端點
26             Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,ProtocolType.Udp);//定義一個Socket
27             newsock.Bind(ipep);//Socket與本地的一個終結點相關聯
28             Console.WriteLine("Waiting for a client.....");
29 
30             IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);//定義要發送的計算機的地址
31             EndPoint Remote = (EndPoint)(sender);//
32             recv = newsock.ReceiveFrom(data, ref Remote);//接受數據          
33             Console.WriteLine("Message received from{0}:", Remote.ToString());
34             Console.WriteLine(Encoding.ASCII.GetBytes(data,0,recv));
35 
36             string welcome = "Welcome to my test server!";
37             data = Encoding.ASCII.GetBytes(welcome);
38             newsock.SendTo(data, data.Length, SocketFlags.None, Remote);
39             while (true)
40             {
41                 data = new byte[1024];
42                 recv = newsock.ReceiveFrom(data, ref Remote);
43                 Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
44                 newsock.SendTo(data, recv, SocketFlags.None, Remote);
45             }
46         }
47     }
48 }
49     對於接收流入的UDP服務器程序來說,必須將程序與本地系統中指定的UDP端口進行綁定。這就可以通過使用合適的本地IP地址創建一個IPEndPoint對象,以及何時的UDP端口號。上述范例程序中的UDP服務器能夠在端口9050從網絡上接收任意流入的UDP數據包。
50    (3)UDP客戶機
51     UDP客戶機程序與服務器程序非常類似。
52     因為客戶機不需要在指定的UDP端口等待流入的數據,因此,不使用Bind()方法,而是使用在數據發送時系統隨機指定的一個UDP端口,而且使用同一個端口接收返回的消息。在看法產品時,要為客戶機指定一套UDP端口,以便服務器和客戶機程序使用相同的端口號。UDP客戶機程序首先定義一個IPEndPoint,UDP服務器將發送數據包到這個IPEndPoint。如果在遠程設備上運行UDP服務器程序,在IPEndPoint定義中必須輸入適當的IP地址和UDP端口號信息。
53 using System;
54 using System.Collections.Generic;
55 using System.Text;
56 using System.Net;
57 using System.Net.Sockets;
58 namespace SimpleUdpClient
59 {
60     class Program
61     {
62         static void Main(string[] args)
63         {
64             byte[] data = new byte[1024];//定義一個數組用來做數據的緩沖區
65             string input, stringData;
66             IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);
67             Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
68             string welcome = "Hello,are you there?";
69             data = Encoding.ASCII.GetBytes(welcome);
70             server.SendTo(data, data.Length, SocketFlags.None, ipep);//將數據發送到指定的終結點
71 
72             IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
73             EndPoint Remote = (EndPoint)sender;
74             data = new byte[1024];
75             int recv = server.ReceiveFrom(data, ref Remote);//接受來自服務器的數據
76 
77             Console.WriteLine("Message received from{0}:", Remote.ToString());
78             Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
79             while (true)//讀取數據
80             {
81                 input = Console.ReadLine();//從鍵盤讀取數據
82                 if (input == "text")//結束標記
83                 {
84                     break;
85                 }
86                 server.SendTo(Encoding.ASCII.GetBytes(input), Remote);//將數據發送到指定的終結點Remote
87                 data = new byte[1024];
88                 recv = server.ReceiveFrom(data, ref Remote);//從Remote接受數據
89                 stringData = Encoding.ASCII.GetString(data, 0, recv);
90                 Console.WriteLine(stringData);
91             }
92             Console.WriteLine("Stopping client");
93             server.Close();
94         }
95     }
96 }       
97    (4)測試服務器與客戶機
98     由於條件的限制,測試是在一台電腦上進行的。所以在客戶機的定義中是將發送和接收信息的地址設置為本機的。
99     先啟動服務器,在啟動客戶機,按照提示輸入信息即可。
復制代碼


免責聲明!

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



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