UDP簡介:UDP 是User Datagram Protocol的簡稱, 中文名是用戶數據包協議,是一種無連接的傳輸層協議,提供面向事務的簡單不可靠信息傳送服務。UDP是與TCP相對應的協議,它是面向非連接的協議,它不與對方連接,而直接把數據包發送過去。“面向非連接”就是正式通信前不必與對方建立連接,不管對方狀態就直接發送。
UDP特性:
(1)UDP是一個無連接協議,傳輸數據之前,源端和終端不建立連接,當它想傳送時就簡單的抓取來自應用程序的數據,並盡可能快的把他扔到網絡上。在發送端UDP傳送的速度僅僅是受應用程序數據生成的速度、計算機能力和傳輸帶寬限制;在接收端,UDP把每個消息段放在隊列中,應用程序每次從隊列中讀取一個消息段。
(2)由於傳輸數據不建立連接,因此也就不需要維護連接狀態,包括收發狀態等,因此一台服務機可同時向多台客戶機傳輸相同的信息。
(3)UDP信息包的標題很短,只有8個字節,相對於TCP的20個字節信息包的額外開銷很小。
(4)吞吐量不受擁擠控制算法的調節,只受應用軟件生成數據的速率、傳輸寬帶、源端和終端主機性能的限制。
(5)UDP使用盡量最大努力交付,即不保證可靠交付,因此主機不需要維持復雜的鏈接狀態表(該表中有許多參數)。
(6)UDP是面向報文的。發送方對應用程序交下來的報文,在添加首部后就向下交付個IP層。既不拆分,也不合並,而是保留這些報文的邊界,因此,應用程序需要選擇合適的報文大小。
示例:在解決方案創建兩個控制台程序:UDPSender,UDPReceive
備注:
(1)vs2012啟動兩個項目需設置:右鍵解決方案->通用屬性->啟動項目->多啟動項目->勾選你要啟動的多個項目->確定->啟動
(2)vs2012始終能看到解決方案的設置:工具->配置->項目和解決方案->常規->總是顯示解決方案
(3)IPEndPoint類包含應用程序連接到主機的服務所需的主機和本地或遠程端口信息。通過組合服務的主機IP地址和端口號,IPEndPoint形成到服務的連接點。
客戶端:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace UDPSender
{
class program
{
static void main(String[] args)
{
byte[] data = new byte[1024];
string input,stringData;
Console.WriteLine("this is a Client.host name is {0}",Dns.GetHostName());
//設置服務器IP和端口號
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"),8001);
//定義網絡類型,數據連接類型和網絡協議UDP
Socket server = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
string welcome = "Hello! I am a Client";
data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data,data.Length,SocketFlags.None,ipep);
IPEndPoint sender = new IPEndPoint(IPAddress.Any,0);
EndPoint Remote = (EndPoint)sender;
data = new byte[1024];
//對於不存在的IP地址,加入此行代碼后,可以在指定時間內解除阻塞模式限制
//server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 100);
int recv = server.ReceiveFrom(data,ref Remote);
Console.WriteLine("Message received from {0}: ", Remote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
while(true)
{
input = Console.ReadLine();
if(input == "exit")
{
break;
}
server.SendTo(Encoding.ASCII.GetBytes(input),Remote);
data = new byte[1024];
recv = server.ReceiveFrom(data,ref Remote);
stringData = Encoding.ASCII.GetString(data,0,recv);
Console.WriteLine(stringData);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace UDPReceive
{
class Program
{
static void main(String[] args)
{
int recv;
byte[] data = new byte[1024];
//得到本機IP,設置端口號
IPEndPoint ipep = new IPEndPoint(IPAddress.Any,8001);
Socket newsock = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.UDP);
//綁定網絡地址
newsock.Bind(ipep);
Console.WriteLine("This is a Server, host name is {0}", Dns.GetHostName());
//等待客戶機連接
Console.WriteLine("Waiting for a client");
//得到客戶端IP
IPEndPoint sender= new IPEndPoint(IPAddress.Any,0);
EndPoint Remote = (EndPoint)(sender);
//接受數據
recv = newsock.ReceiveFrom(data,ref Remote);
Console.WriteLine("Message received from {0}",Remote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data,0,recv));
//客戶端連接成功后,發送信息
string welcome = "Hi I am a Server";
data = Encoding.ASCII.GetByte(welcome);
//發送信息
newsock.SendTo(data,data.Length,SocketFlags.None,Remote);
while(true)
{
data = new byte[1024];
//發送接受的信息
recv = newsock.ReceiveFrom(data,ref Remote);
Console.WriteLine(Encoding.ASCII.GetString(data,0,recv));
newsock.SendTo(data,recv,SocketFlags.None,Remote);
}
}
}
}
