UDP (User Datagram Protocol) 是一种无连接的传输层协议,主要用于支持数据报文的传输。它的主要特点包括简单、高效、不保证可靠性和顺序。
1.UDP协议基本概念
1.udp基于IP的简单的协议,不可靠的协议
2.优点:简单、 轻量化、 传输速度高、要求可靠性不太高
3.缺点:没有流量控制,没有应答确认机制。不能解决丢包重发错顺序问题
2.UDP 特点:
• 建立连接:与 TCP 不同,UDP 在发送数据前不需要建立连接。这意味着发送方可以直接向接收方发送数据报文。
• 发送数据:发送方向接收方发送数据报文时,每个数据报文都包含源端口、目的端口、长度和校验和等信息。这些信息被封装在 UDP 头部中,随后数据报文被传递给 IP 层进行发送。
• 接收数据:接收方接收到数据报文后,会检查 UDP 头部中的校验和以验证数据的完整性。如果校验和正确,接收方将数据报文传递给上层应用程序;如果校验和错误,数据报文会被丢弃。
• 无确认机制:UDP 不提供数据传输的确认机制,这意味着发送方不会收到接收方关于是否成功接收到数据的反馈。因此,UDP 不能保证数据的可靠传输。
• 无序传输:UDP 不保证数据报文的顺序,即发送方发送的数据报文可能以不同的顺序到达接收方。这要求上层应用程序自行处理数据的排序问题。
• 多播和广播:UDP 支持多播和广播通信,允许多个接收方同时接收相同的数据报文,适用于视频流媒体、在线游戏等应用场景。
3.UDP示例
UDP 服务器
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class UdpServer
{
private const int Port = 5000;
private const int BufferSize = 1024;
static void Main(string[] args)
{
// 创建一个 UDP 套接字
UdpClient udpClient = new UdpClient(Port);
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, Port);
Console.WriteLine("UDP Server is running...");
while (true)
{
try
{
// 接收数据报文
byte[] receivedBytes = udpClient.Receive(ref remoteEndPoint);
string receivedData = Encoding.UTF8.GetString(receivedBytes);
Console.WriteLine($"Received data from {remoteEndPoint}: {receivedData}");
// 发送响应
string responseData = "Message received!";
byte[] sendBytes = Encoding.UTF8.GetBytes(responseData);
udpClient.Send(sendBytes, sendBytes.Length, remoteEndPoint);
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
}
UDP 客户端
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class UdpClientExample
{
private const int Port = 5000;
private const string ServerIp = "127.0.0.1";
private const int BufferSize = 1024;
static void Main(string[] args)
{
// 创建一个 UDP 套接字
UdpClient udpClient = new UdpClient();
// 设置服务器的 IP 地址和端口
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(ServerIp), Port);
Console.WriteLine("UDP Client is running...");
while (true)
{
try
{
Console.Write("Enter message to send: ");
string message = Console.ReadLine();
byte[] sendBytes = Encoding.UTF8.GetBytes(message);
// 发送数据报文
udpClient.Send(sendBytes, sendBytes.Length, serverEndPoint);
// 接收响应
byte[] receivedBytes = udpClient.Receive(ref serverEndPoint);
string receivedData = Encoding.UTF8.GetString(receivedBytes);
Console.WriteLine($"Received response from server: {receivedData}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
}
4.UDP 的应用场景
以下展示 UDP 在不同应用场景中的优势,尤其是在对实时性要求较高的场景中。
1. 在线视频会议
场景描述: 在线视频会议应用(如 Zoom、Teams)通常使用 UDP 协议来传输音视频数据。
• 发送数据:发送方(例如会议主持人)的摄像头和麦克风捕获音视频数据,这些数据被编码成小的数据包,并通过 UDP 发送到接收方。
• 接收数据:接收方(例如参会者)接收到这些数据包后,解码并显示音视频内容。
• 无确认机制:由于 UDP 不提供确认机制,即使某些数据包丢失,也不会重新发送,这有助于减少延迟,保证实时性。
• 无序传输:接收方可能会接收到乱序的数据包,但视频编解码器通常能够处理这种情况,确保视频流畅播放。
2. 在线游戏
场景描述: 多人在线游戏(如《英雄联盟》、《绝地求生》)通常使用 UDP 协议来传输游戏状态数据。
• 发送数据:服务器或客户端定期发送游戏状态更新(如玩家位置、生命值等)到其他客户端。
• 接收数据:接收方客户端接收到这些状态更新后,更新本地的游戏状态。
• 无确认机制:即使某些状态更新数据包丢失,也不会影响整体游戏体验,因为后续的状态更新会覆盖之前的旧数据。
• 无序传输:游戏引擎通常能够处理乱序的数据包,确保游戏状态的准确性和实时性。
3. DNS 查询
场景描述: DNS(域名系统)查询通常使用 UDP 协议来解析域名。
• 发送数据:客户端(如浏览器)向 DNS 服务器发送一个包含域名的查询请求。
• 接收数据:DNS 服务器接收到查询请求后,查找对应的 IP 地址,并将结果返回给客户端。
• 无确认机制:如果客户端没有收到响应,它可能会重发查询请求,但不会等待确认。
• 无序传输:DNS 查询通常是一次性的,所以无序传输不是问题。
4. 多播视频流
场景描述: 多播视频流(如 IPTV)使用 UDP 协议将视频数据同时发送给多个接收方。
• 发送数据:视频服务器将视频数据包发送到一个多播地址。
• 接收数据:所有订阅了该多播地址的接收方都能接收到这些数据包。
• 无确认机制:即使某些数据包丢失,也不会重新发送,以保证视频流的实时性。
• 无序传输:接收方可能会接收到乱序的数据包,但视频编解码器通常能够处理这种情况,确保视频流畅播放。
在某些场景,为什么用UDP,而不用TCP呢?
打个比方:就拿视频来说,哪怕是某一时刻网络不好导致数据丢包了,那也影响也不大,顶多就是卡了一下或者花屏了一下,下一帧的数据包马上就顶替上一次的数据了,实际对我们来说还是可接受的,由此可说,当运用在可靠性低
、时效性
、快速
高这场景下使用最合适不过了
要是换成TCP,有可能视频会卡的很严重,无法直视,因为TCP 出现丢包了,还需要等丢的包发过来才行,这过程延迟就很高了
5.总结
UDP 提供了一种快速、简单的数据传输方式,适用于对传输速度有较高要求而对可靠性要求相对较低的应用场景。