初始化CRICS
This commit is contained in:
97
RCUHost/NewUDP/UdpEndpoint.cs
Normal file
97
RCUHost/NewUDP/UdpEndpoint.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user