202 lines
4.9 KiB
C#
202 lines
4.9 KiB
C#
using System;
|
|
using System.ComponentModel;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
|
|
namespace NetWorkHelper
|
|
{
|
|
public class UdpLibrary : IDisposable
|
|
{
|
|
#region 构造函数
|
|
public UdpLibrary(int port)
|
|
{
|
|
Port = port;
|
|
}
|
|
public UdpLibrary()
|
|
{
|
|
//默认监听端口1234
|
|
Port = 1234;
|
|
}
|
|
#endregion
|
|
|
|
#region 变量
|
|
private UdpClient _udpClient;
|
|
private bool _started;
|
|
#endregion
|
|
|
|
#region 属性
|
|
[Description("UDP监听端口")]
|
|
[Category("UDP服务端")]
|
|
public int Port { get; set; } = 1234;
|
|
|
|
[Description("UDP客户端")]
|
|
[Category("UDP服务端")]
|
|
internal UdpClient UdpClient
|
|
{
|
|
get
|
|
{
|
|
if (_udpClient == null)
|
|
{
|
|
bool success = false;
|
|
while (!success)
|
|
{
|
|
try
|
|
{
|
|
_udpClient = new UdpClient(Port);
|
|
success = true;
|
|
}
|
|
catch (SocketException ex)
|
|
{
|
|
Port++;
|
|
if (Port > 65535)
|
|
{
|
|
success = true;
|
|
throw ex;
|
|
}
|
|
}
|
|
}
|
|
|
|
uint IOC_IN = 0x80000000;
|
|
uint IOC_VENDOR = 0x18000000;
|
|
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
|
|
_udpClient.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
|
|
}
|
|
return _udpClient;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 方法
|
|
public void Start()
|
|
{
|
|
if (!_started)
|
|
{
|
|
_started = true;
|
|
ReceiveInternal();
|
|
}
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
try
|
|
{
|
|
_started = false;
|
|
UdpClient.Close();
|
|
_udpClient = null;
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
|
|
public void Send(IDataCell cell, IPEndPoint remoteIP)
|
|
{
|
|
byte[] buffer = cell.ToBuffer();
|
|
SendInternal(buffer, remoteIP);
|
|
}
|
|
|
|
public void Send(byte[] buffer, IPEndPoint remoteIP)
|
|
{
|
|
SendInternal(buffer, remoteIP);
|
|
}
|
|
|
|
protected void SendInternal(byte[] buffer, IPEndPoint remoteIP)
|
|
{
|
|
if (!_started)
|
|
{
|
|
throw new ApplicationException("UDP Closed.");
|
|
}
|
|
try
|
|
{
|
|
UdpClient.BeginSend(buffer, buffer.Length, remoteIP, new AsyncCallback(SendCallback), null);
|
|
}
|
|
catch (SocketException ex)
|
|
{
|
|
throw ex;
|
|
}
|
|
}
|
|
|
|
public bool IsStarted()
|
|
{
|
|
return _started;
|
|
}
|
|
protected void ReceiveInternal()
|
|
{
|
|
if (!_started)
|
|
{
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
UdpClient.BeginReceive(new AsyncCallback(ReceiveCallback), null);
|
|
}
|
|
catch (SocketException ex)
|
|
{
|
|
//_started = false;
|
|
throw ex;
|
|
}
|
|
}
|
|
|
|
void SendCallback(IAsyncResult result)
|
|
{
|
|
try
|
|
{
|
|
UdpClient.EndSend(result);
|
|
}
|
|
catch (SocketException ex)
|
|
{
|
|
throw ex;
|
|
}
|
|
}
|
|
|
|
void ReceiveCallback(IAsyncResult result)
|
|
{
|
|
if (!_started)
|
|
{
|
|
return;
|
|
}
|
|
IPEndPoint remoteIP = new IPEndPoint(IPAddress.Any, 0);
|
|
byte[] buffer = null;
|
|
try
|
|
{
|
|
buffer = UdpClient.EndReceive(result, ref remoteIP);
|
|
}
|
|
catch (SocketException ex)
|
|
{
|
|
throw ex;
|
|
}
|
|
finally
|
|
{
|
|
ReceiveInternal();
|
|
}
|
|
|
|
OnReceiveData(new ReceiveDataEventArgs(buffer, remoteIP));
|
|
}
|
|
#endregion
|
|
|
|
#region IDisposable 成员
|
|
|
|
public void Dispose()
|
|
{
|
|
_started = false;
|
|
if (_udpClient != null)
|
|
{
|
|
_udpClient.Close();
|
|
_udpClient = null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 事件
|
|
public event ReceiveDataEventHandler ReceiveData;
|
|
[Description("UDP服务端接收数据事件")]
|
|
[Category("UDPServer事件")]
|
|
protected virtual void OnReceiveData(ReceiveDataEventArgs e)
|
|
{
|
|
ReceiveData?.Invoke(this, e);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|