You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
3.4 KiB
125 lines
3.4 KiB
using Apewer;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
using System.Threading;
|
|
|
|
namespace Apewer.Network
|
|
{
|
|
|
|
/// <summary>UDP 服务端。</summary>
|
|
public class UdpServer : IDisposable
|
|
{
|
|
|
|
/// <summary>释放资源。</summary>
|
|
public void Dispose() { Quit(); }
|
|
|
|
private Thread _thread = null;
|
|
private System.Net.Sockets.UdpClient _udp = null;
|
|
|
|
private string _address = "0.0.0.0";
|
|
private int _port = 0;
|
|
|
|
/// <summary>Exception。</summary>
|
|
public Event<Exception> Excepted { get; set; }
|
|
|
|
/// <summary>服务端已启动。</summary>
|
|
public Event Started { get; set; }
|
|
|
|
/// <summary>服务端已关闭。</summary>
|
|
public Event Quitted { get; set; }
|
|
|
|
/// <summary>已收到客户端数据。</summary>
|
|
public Event<SocketReceived> Received { get; set; }
|
|
|
|
/// <summary>构造函数。</summary>
|
|
public UdpServer()
|
|
{
|
|
}
|
|
|
|
/// <summary>服务端是否正在运行。</summary>
|
|
public bool Alive
|
|
{
|
|
get { return (_thread != null) ? _thread.IsAlive : false; }
|
|
}
|
|
|
|
/// <summary>指定监听地址,默认为 0.0.0.0。</summary>
|
|
public string Address
|
|
{
|
|
get { return _address; }
|
|
set { if (!Alive) _address = string.IsNullOrEmpty(value) ? "" : value; }
|
|
}
|
|
|
|
/// <summary>获取或设置服务端端口。</summary>
|
|
public int Port
|
|
{
|
|
get { return _port; }
|
|
set
|
|
{
|
|
int vp = value;
|
|
if (vp < 0) vp = 0;
|
|
if (vp > 65535) vp = 65535;
|
|
if (!Alive) _port = vp;
|
|
}
|
|
}
|
|
|
|
/// <summary>启动服务端。</summary>
|
|
public void Start()
|
|
{
|
|
Quit();
|
|
var isIP = NetworkUtility.IsIP(_address);
|
|
if (isIP && (Port > 0))
|
|
{
|
|
_thread = new Thread(Listener);
|
|
_thread.IsBackground = true;
|
|
_thread.Start();
|
|
}
|
|
}
|
|
|
|
/// <summary>关闭服务端。</summary>
|
|
public void Quit()
|
|
{
|
|
if (_thread != null)
|
|
{
|
|
if (_thread.IsAlive) _thread.Abort();
|
|
_thread = null;
|
|
}
|
|
if (_udp != null)
|
|
{
|
|
_udp.Close();
|
|
_udp = null;
|
|
Quitted?.Invoke(this);
|
|
}
|
|
}
|
|
|
|
private void Listener()
|
|
{
|
|
try
|
|
{
|
|
var ep = new IPEndPoint(IPAddress.Any, Port);
|
|
_udp = new System.Net.Sockets.UdpClient(ep);
|
|
Started?.Invoke(this);
|
|
while (true)
|
|
{
|
|
var bytes = _udp.Receive(ref ep);
|
|
if ((Received != null) && (bytes.Length > 0))
|
|
{
|
|
var ip = ep.Address.ToString();
|
|
var port = ep.Port;
|
|
Received?.Invoke(this, new SocketReceived(ip, ep.Port, bytes));
|
|
}
|
|
// Thread.Sleep(1);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (Excepted != null) Excepted(this, ex);
|
|
}
|
|
Quitted.Invoke(this);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|