UDP通信
UDP通信的主要好处在于其低延迟、实时、简单高效、支持广播和多播、无拥塞控制以及适用于特定应用场景
- 无连接特性:UDP不需要在通信前建立连接,因此减少了建立连接的开销和延迟。
- 实时性:适用于对实时性要求高的应用,如音频、视频流、在线游戏等,因为这些应用更关注数据的即时传输,而不是数据的完整性。
- 不会粘包,TCP使用字节流传输会导致粘包
服务端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleAppUDP
{
public class UDP_test
{
/// <summary>
/// Udp 服务端
/// </summary>
public static void Run()
{
//服务端
UdpClient udpServer = new UdpClient(11000);
try
{
Console.WriteLine("UDP服务器已启动,正在等待消息...");
while (true)
{
try
{
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
byte[] data = udpServer.Receive(ref remoteEP);
Console.WriteLine($"收到连接{remoteEP.ToString()}...");
string message = Encoding.UTF8.GetString(data);
Console.WriteLine($"收到来自{remoteEP}的消息{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}: {message}");
// 发送响应回客户端
string response = $"我已收到:{message}";
byte[] responseData = Encoding.UTF8.GetBytes(response);
udpServer.Send(responseData, responseData.Length, remoteEP);
}
catch (Exception ex)
{
Console.WriteLine("处理异常," + ex.Message);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
udpServer?.Close();
udpServer?.Dispose();
}
}
}
}
客户端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleAppClient
{
public class UdpClinent
{
//public delegate void PushMsg(string msg);
event EventHandler<string> PushMsg;
UdpClient udpClient = new UdpClient();
//~UdpClinent() {
// //退出程序是,需要关闭连接
// udpClient?.Close();
// udpClient?.Dispose();
//}
/// <summary>
/// 连接udp服务器
/// </summary>
public void ConnectionServer()
{
try
{
udpClient.Connect("localhost", 11000);
string message = $"你好,UDP服务器!{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}";
byte[] data = Encoding.UTF8.GetBytes(message);
udpClient.Send(data, data.Length);
//发送消息到服务器
PushMsg += (o, msg) =>
{
byte[] data = Encoding.UTF8.GetBytes(msg);
udpClient.Send(data, data.Length);
};
//接收服务器消息
Task.Run(() =>
{
while (true)
{
try
{
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
byte[] receivedData = udpClient.Receive(ref remoteEP);
string receivedMessage = Encoding.UTF8.GetString(receivedData);
Console.WriteLine($"收到服务器的响应{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}: {receivedMessage}");
}
catch (Exception ex)
{
Console.WriteLine("接收消息失败," + ex.ToString());
}
}
});
//Task.Delay(-1).Wait();
}
catch (Exception e)
{
udpClient?.Close();
udpClient?.Dispose();
Console.WriteLine("连接UDP服务器失败" + e.ToString());
Task.Delay(3000).Wait();
ConnectionServer();
}
finally
{
//退出程序时,需要关闭连接
//udpClient?.Close();
//udpClient?.Dispose();
}
}
/// <summary>
/// 发送消息到udp服务器
/// </summary>
/// <param name="msg"></param>
public void SendMsgToServer(string msg)
{
try
{
PushMsg?.Invoke(1, msg);
}
catch (Exception ex)
{
Console.WriteLine( "发送消息失败,"+ex.Message);
}
}
}
}
客户端发送消息
// See https://aka.ms/new-console-template for more information
using System.Net.Sockets;
using System.Net;
using System.Text;
using ConsoleAppClient;
Console.WriteLine("客户端,连接udp服务器");
//UdpClinent.ConnectionServer();
UdpClinent udpClinent = new UdpClinent();
udpClinent.ConnectionServer();
while (true)
{
udpClinent.SendMsgToServer("测试消息");
//Task.Delay(2 * 1000).Wait();
}