什么是UDP通信
UDP(User Datagram Protocol,用户数据报协议)通信是一种在计算机网络中使用的传输层通信协议,以下是关于它的详细介绍:
- 基本概念:UDP 是一种无连接的协议,它在数据传输时不需要先建立连接,就可以直接将数据报发送到目标地址。这就好比写信,你不需要事先通知对方就可以直接把信寄出去,对方收到信后也不会给你发送确认收到的消息。
- 工作原理:UDP 通信中,发送方将数据封装成 UDP 数据包,每个数据包包含源端口号、目的端口号、数据长度和数据等信息。然后,这些数据包通过网络传输到接收方。接收方根据目的端口号来接收和处理数据。由于 UDP 没有建立连接的过程,也没有确认机制,所以它不保证数据一定能准确无误地到达接收方,也不保证数据的接收顺序和发送顺序一致。
- 特点
- 简单高效:因为不需要建立和维护连接,所以 UDP 的开销小,传输速度快,适合对实时性要求高的应用,如视频直播、音频通话等。在这些应用中,偶尔丢失一些数据对整体的观看或收听体验影响不大,但如果因为建立连接等操作导致延迟过高,就会严重影响用户体验。
- 无连接性:发送方可以随时向接收方发送数据,不受连接状态的限制,比较灵活。
- 不可靠性:UDP 不提供数据的可靠性传输,可能会出现数据丢失、重复或乱序的情况。例如,在网络拥塞时,数据包可能会被丢弃。
- 应用场景
- 实时音视频传输:如视频会议、在线游戏等。在这些场景中,数据的实时性至关重要,少量的数据丢失可以接受,因为重新传输可能会导致更大的延迟,影响用户体验。
- 域名系统(DNS):DNS 用于将域名转换为 IP 地址,通常使用 UDP 协议进行查询和响应。因为 DNS 查询通常比较简单,而且对速度要求较高,UDP 的快速传输特性能够满足其需求。
- 简单网络管理协议(SNMP):用于管理和监控网络设备。SNMP 代理使用 UDP 将设备信息发送给管理站,由于对实时性有一定要求,且数据量通常不大,UDP 是合适的选择。
UDP和TCP通讯的区别
UDP 和 TCP 是两种常用的传输层协议,它们的设计目标和特性有显著差异,以下是具体对比:
1. 连接性
UDP(无连接)
无需建立连接即可直接发送数据,类似 “写信”:
发送方直接将数据包(数据报)发往接收方,不关心对方是否在线或能否接收。
典型场景:DNS 查询、视频直播。TCP(面向连接)
必须先建立连接(三次握手),类似 “打电话”:
发送方和接收方需确认连接状态后才传输数据,确保通信双方就绪。
典型场景:网页浏览(HTTP)、文件传输(FTP)。
2. 可靠性
UDP(不可靠)
- 不保证数据送达、不重复、不丢包、按序到达。
- 若数据丢失或乱序,不重传、不排序。
适用场景:对实时性要求高(如游戏、语音通话),少量丢包可接受。
TCP(可靠)
- 通过确认机制(ACK)、重传机制(超时重传)、序列号保证数据完整且按序到达。
- 若数据丢失或乱序,自动重传并排序。
适用场景:对数据完整性要求高(如文件下载、银行交易)。
3. 传输效率与开销
UDP
- 首部开销小(仅 8 字节),无连接建立和维护成本。
- 传输速度快,适合小数据量、低延迟场景。
TCP
- 首部开销大(至少 20 字节),需维护连接状态(如序列号、确认号)。
- 包含拥塞控制机制(避免网络拥堵),可能因重传导致延迟。
注:TCP 的可靠性是以牺牲速度和带宽为代价的。
4. 传输模式
UDP(数据报)
- 数据以独立数据包传输,边界清晰(发送方发一个包,接收方收一个包)。
- 示例:发送 “ABC” 和 “DEF”,接收方可能收到两个独立数据包。
TCP(字节流)
- 数据以连续字节流传输,无边界概念(发送方分多次发送,接收方可能一次性读取)。
- 示例:发送 “ABC” 和 “DEF”,接收方可能收到 “ABCDEF” 一个整体。
用Unity做客户端实现UDP同步通信逻辑
撰写C#脚本
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine;
public class Lesson14 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
#region 实现UDP客户端通信 收发字符串
//1.创建套接字
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//2.绑定本机地址
IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8080);
socket.Bind(ipPoint);
//3.发送到指定目标
IPEndPoint remoateIp = new IPEndPoint(IPAddress.Parse("127.0.0.1"),8081);
//指定要发送的字节数和远程计算机的IP和端口
socket.SendTo(Encoding.UTF8 .GetBytes ("我是客户端,你好"), remoateIp);
//4.接收消息
byte[] bytes = new byte[512];
//这个变量主要是用来记录 谁发的消息给你 传入函数后 在内部 它会帮助我们进行赋值
EndPoint remoateIp2 = new IPEndPoint(IPAddress.Any, 0);
int length= socket.ReceiveFrom(bytes, ref remoateIp2);
print("IP:"+(remoateIp2 as IPEndPoint).Address .ToString()
+"Port:"+(remoateIp2 as IPEndPoint).Port
+"发来了:"+Encoding.UTF8.GetString(bytes, 0, length));
//5.释放关闭
socket.Shutdown(SocketShutdown.Both);
socket.Close();
#endregion
}
// Update is called once per frame
void Update()
{
}
}
用本地做服务器实现UDP同步通信逻辑
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace UDPServer
{
class Program
{
static void Main(string[] args)
{
#region 实现UDP服务端通信收发字符串
//1.创建套接字
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//2.绑定本机地址
IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8081);
socket.Bind(ipPoint);
Console.WriteLine("服务器开启成功");
//3.接收消息
byte[] bytes = new byte[512];
EndPoint remoateIp2 = new IPEndPoint(IPAddress.Any, 0);
int length = socket.ReceiveFrom(bytes, ref remoateIp2);
Console .WriteLine("IP:" + (remoateIp2 as IPEndPoint).Address.ToString()
+ "Port:" + (remoateIp2 as IPEndPoint).Port
+ "发来了:" + Encoding.UTF8.GetString(bytes, 0, length));
//4.发送到指定地址
socket.SendTo(Encoding.UTF8.GetBytes("欢迎给服务器发消息"), remoateIp2);
//5.释放关闭
socket.Shutdown(SocketShutdown.Both);
socket.Close();
#endregion
Console.ReadKey();
}
}
}
实现结果
将脚本挂载到Unity场景中,运行服务器,成功实现客户端与服务器UDP同步通信