namespace SimpleUdp { using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Collections.Concurrent; internal class State { internal State(int bufferSize) { Buffer = new byte[bufferSize]; } internal byte[] Buffer = null; } public class UdpEndpoint : IDisposable { private Socket _Socket = null; private int _MaxDatagramSize = 65507; private EndPoint _Endpoint = new IPEndPoint(IPAddress.Any, 0); private SemaphoreSlim _SendLock = new SemaphoreSlim(1, 1); public UdpEndpoint(string ip, int port) { var ipAddress = IPAddress.Parse(ip); _Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); _Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); _Socket.Bind(new IPEndPoint(ipAddress, port)); State state = new State(_MaxDatagramSize); _Socket.BeginReceiveFrom(state.Buffer, 0, _MaxDatagramSize, SocketFlags.None, ref _Endpoint, ReceiveCallback, state); } private void ReceiveCallback(IAsyncResult ar) { try { State so = (State)ar.AsyncState; int bytes = _Socket.EndReceiveFrom(ar, ref _Endpoint); if (bytes > 0 && bytes < so.Buffer.Length) { byte[] buffer = new byte[bytes]; Buffer.BlockCopy(so.Buffer, 0, buffer, 0, bytes); // 直接使用接收到的 EndPoint 进行回复 string senderIpPort = _Endpoint.ToString(); string[] parts = senderIpPort.Split(':'); if (parts.Length == 2) { SendInternal(parts[0], int.Parse(parts[1]), new byte[] { 0x01, 0x01 }); } } // 继续接收 _Socket.BeginReceiveFrom(so.Buffer, 0, _MaxDatagramSize, SocketFlags.None, ref _Endpoint, ReceiveCallback, so); } catch (Exception ex) { // 处理异常 } } private void SendInternal(string ip, int port, byte[] data) { _SendLock.Wait(); try { IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ip), port); // 使用同一个 Socket 发送回复 _Socket.SendTo(data, remoteEP); } finally { _SendLock.Release(); } } public void Dispose() { _Socket.Close(); _Socket.Dispose(); } } }