C# 网络编程之UDP
什么是UDP
UDP是一个无连接的传输协议,它不保证可靠传输和数据的顺序,但是其传输速度很快,适合于传输实时性要求高的数据。
UDP的使用场景
由于UDP不需要建立连接,所以适合于一对多或多对多的广播传输。比如实现网络游戏的消息传输,实时视频传输等。
UDP编程实现
发送端实现
UDP发送方需要绑定发送端口,然后指定目标地址和目标端口,将要发送的数据包发送出去。
示例1:发送一个简单的字符串。
using System.Net;
using System.Net.Sockets;
using System.Text;
class Sender {
static void Main() {
var endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345);
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) {
byte[] data = Encoding.UTF8.GetBytes("Hello World!");
socket.SendTo(data, endPoint);
}
}
}
示例2:发送一个自定义的数据包。
using System;
using System.Net;
using System.Net.Sockets;
struct CustomPacket {
public int id;
public float x;
public float y;
public float z;
}
class Sender {
static void Main() {
var endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345);
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) {
var packet = new CustomPacket {
id = 123,
x = 1.0f,
y = 2.0f,
z = 3.0f
};
byte[] data = Serialize(packet);
socket.SendTo(data, endPoint);
}
}
// 自定义的序列化方法
static byte[] Serialize<T>(T obj) {
int size = System.Runtime.InteropServices.Marshal.SizeOf(typeof(T));
byte[] data = new byte[size];
var ptr = System.Runtime.InteropServices.Marshal.AllocHGlobal(size);
System.Runtime.InteropServices.Marshal.StructureToPtr(obj, ptr, true);
System.Runtime.InteropServices.Marshal.Copy(ptr, data, 0, size);
System.Runtime.InteropServices.Marshal.FreeHGlobal(ptr);
return data;
}
}
接收端实现
UDP接收方需要绑定监听端口,然后不断从网络中读取数据包。
示例1:接收简单的字符串。
using System.Net;
using System.Net.Sockets;
using System.Text;
class Receiver {
static void Main() {
var endPoint = new IPEndPoint(IPAddress.Any, 12345);
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) {
socket.Bind(endPoint);
byte[] buffer = new byte[1024];
int size = socket.Receive(buffer);
string message = Encoding.UTF8.GetString(buffer, 0, size);
Console.WriteLine(message);
}
}
}
示例2:接收自定义的数据包。
using System;
using System.Net;
using System.Net.Sockets;
struct CustomPacket {
public int id;
public float x;
public float y;
public float z;
}
class Receiver {
static void Main() {
var endPoint = new IPEndPoint(IPAddress.Any, 12345);
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) {
socket.Bind(endPoint);
byte[] buffer = new byte[1024];
int size = socket.Receive(buffer);
var packet = Deserialize<CustomPacket>(buffer, size);
Console.WriteLine(packet.id);
Console.WriteLine(packet.x);
Console.WriteLine(packet.y);
Console.WriteLine(packet.z);
}
}
// 自定义的反序列化方法
static T Deserialize<T>(byte[] buffer, int size) {
T obj = default(T);
int objSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(T));
if (size == objSize) {
var ptr = System.Runtime.InteropServices.Marshal.AllocHGlobal(objSize);
System.Runtime.InteropServices.Marshal.Copy(buffer, 0, ptr, objSize);
obj = (T)System.Runtime.InteropServices.Marshal.PtrToStructure(ptr, typeof(T));
System.Runtime.InteropServices.Marshal.FreeHGlobal(ptr);
}
return obj;
}
}
UDP总结
UDP是一个高速传输的无连接协议,适合于实时性要求高的数据传输。使用UDP需要我们手动处理数据包的组装和拆解,同时对于丢包和乱序等问题需要自行处理。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C# 网络编程之UDP - Python技术站