UDP协议
Internet 协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。RFC 768 描述了 UDP。
Internet 的传输层有两个主要协议,互为补充。无连接的是 UDP,它除了给应用程序发送数据包功能并允许它们在所需的层次上架构自己的协议之外,几乎没有做什么特别的事情。面向连接的是 TCP,该协议几乎做了所有的事情。
UDP的优缺点
优点:
1,传输数据之前通信双方不需要建立连接,因此不存在连接建立的时延。在发送端,UDP 传送数据的速度仅仅受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端, UDP 把每个数据报放在队列中,应用程序每次从队列中读一个数据报。
2,传输数据不需要维护连接状态,包括收发状态等,这样一台服务器可同时向多个客户端传输相同的数据,如实现多播。
缺点:
容易丢包
它不能提供可靠性保证,数据可能会丢失或损坏,因此不适合传输重要的数据。另外,UDP也不能提供流量控制,因此可能会导致网络拥塞。
简单逻辑代码:
#region 单播
/// <summary>
/// 接收
/// </summary>
static void UdpRevice()
{
Socket udp = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
IPEndPoint ipP = new IPEndPoint(IPAddress.Any,8080);
udp.Bind(ipP);
Task.Run(() =>
{
byte[] bytes = new byte[1024];
while (true)
{
EndPoint endP = new IPEndPoint(0,0);
int length = udp.ReceiveFrom(bytes,ref endP);
if (length <= 0)
{
udp.Close();
return;
}
string str = encoding.GetString(bytes,0, length);
Console.WriteLine($"接收到{
endP}发送过来的数据:"+ str);
}
});
}
static void UdpSend()
{
Socket udp = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
Task.Run(() =>
{
//接收方IP和端口
EndPoint endP = new IPEndPoint(IPAddress.Parse("192.168.22.1"),8080);
//循环发送
while (true)
{
byte[] bytes = encoding.GetBytes("发送方发送的数据");
udp.SendTo(bytes, endP);
Task.Delay(1000).Wait();
}
});
}
#endregion
#region 组播
/// <summary>
/// 组播接收数据
/// </summary>
static void MulRevice()
{
UdpClient udp = new UdpClient(8080);
IPAddress ipAddress = IPAddress.Parse("235.0.0.1");
//添加进组
udp.JoinMulticastGroup(ipAddress);
Task.Run(() =>
{
//发送方的IP和端口
IPEndPoint endP = new IPEndPoint(0, 0);
//循环接收数据
while (true)
{
byte[] buffer = udp.Receive(ref endP);
string str = encoding.GetString(buffer);
Console.WriteLine($"组播:接收到的数据:{
str}。发送方的IP和端口:{
endP}");
//回消息,发送数据
byte[] bytes = encoding.GetBytes("接收消息后回消息");
udp.Send(bytes,bytes.Length,endP);
}
});
}
/// <summary>
/// 组播发送数据
/// </summary>
static void MulSend()
{
IPAddress ipAddress =IPAddress.Parse("235.0.0.1");
UdpClient udpTo = new UdpClient(8088);//绑定本地的一个端口号
udpTo.JoinMulticastGroup(ipAddress);
Task.Run(() =>
{
//给组播发数据
IPEndPoint endP = new IPEndPoint(ipAddress,8080);
while (true)
{
byte[] bytes = encoding.GetBytes("给组播发的数据2222");
udpTo.Send(bytes,bytes.Length,endP);
byte[] bytes1 = udpTo.Receive(ref endP);
string str = encoding.GetString(bytes1);
Console.WriteLine($"发送之后,在接收一条接收方回应的消息:{
str}。接收方的IP和端口是:========={
endP}");
Task.Delay(1000).Wait();
}
});
}
#endregion
#region 广播
private static void BroadcastReceive()
{
//自己的端口,别人发送数据时发送到这个端口
UdpClient udpClient = new UdpClient(8080);
Task.Run(() =>
{
IPEndPoint endP = new IPEndPoint(0,0);
//循环接收数据
while (true)
{
//接收数据
byte[] buffer = udpClient.Receive(ref endP);
string str = encoding.GetString(buffer);
//输出
Console.WriteLine($"接收到的广播数据{
str},发送数据的广播的IP和端口{
endP}");
}
});
}
private static void BroadcastSend()
{
//发送时,不写端口,就会随机一个端口发送
UdpClient udp = new UdpClient();
Task.Run(() =>
{
//循环发送广播数据
while (true)
{
//广播IP:255.255.255.255
IPEndPoint endP = new IPEndPoint(IPAddress.Parse("255.255.255.255"),8080);
//循环发送
int num = 1;
while (true)
{
byte[] bytes = encoding.GetBytes("我是广播"+num);
num++;
udp.Send(bytes,bytes.Length,endP);
Task.Delay(1000).Wait();
}
}
});
}
#endregion