根据心跳包的理论来实现 (UDP)
1、 创建UDPConnected模块
public class UdpConnected
{
private bool _isLive;
public IPEndPoint EndPoint {
get; set; }
System.Timers.Timer timer = null;
//设置状态过期时间
private void WaitResponse()
{
timer = new System.Timers.Timer(3000);
timer.Elapsed += delegate (object sender, System.Timers.ElapsedEventArgs a)
{
_isLive = false;
};
timer.Enabled = true;
timer.Start();
}
public bool IsLive
{
get
{
return _isLive;
}
set
{
if (timer != default(System.Timers.Timer))
{
timer.Close();
timer.Dispose();
}
WaitResponse();
_isLive = value;
}
}
}
创建接收upd连接成功的列表容器 List<UdpConnected>
2、 心跳包(每隔一段时间发送一个空数据包)
设置一个优先级低的后台线程来运行
public virtual void Heartbeat(object obj)
{
UdpClient udp = obj as UdpClient;
while (true)
{
_connecteds.ForEach(i =>
{
udp.Send(new byte[0], 0, i.EndPoint);
});
UdpConnectChanged?.Invoke(_connecteds);
Thread.Sleep(1000);
}
}
3、 实际应用
当UDP服务端接收空数据包(byte[0])时即注册连接,当然也可以发送特定的数据模型来建立连接。
//udp server
private IPEndPoint _recvIp=new IPEndPoint(IPAddress.Any,0);//监听任意端口 用于保存连接数据
public virtual void Recv(object obj)
{
UdpClient udp = obj as UdpClient;
while (true)
{
byte[] bRecv = default(byte[]);
try
{
bRecv = udp.Receive(ref _recvIp);
}
catch (Exception ex)
{
continue;
}
var query = _connecteds.Where(i => i.EndPoint.ToString() == _recvIp.ToString()).ToList();
if (bRecv.Length == 0)
{
if (query.Count == 0)
{
_connecteds.Add(new UdpConnected() {
EndPoint = _recvIp, IsLive = true });
}
else if (query.Count == 1)
{
query.First().IsLive = true;
}
else
{
throw new Exception("错误");
}
}
else if (bRecv.Length != 0 && query.Count == 1)
{
//接收消息
OnReceived?.Invoke(bRecv,_recvIp);
}
}
}
Udp 客户端在启动时需要向服务器发送空数据包(byte[0]) 用于验证连接,
并启用后台线程来运行
//client
public virtual void Recv(object obj)
{
UdpClient client= obj as UdpClient;
while (true)
{
byte[] bRecv = default(byte[]);
try
{
bRecv = client.Receive(ref serviceIp);
}
catch (Exception)
{
continue;
}
if (bRecv.Length == 0)
{
byte[] a = new byte[0];
client.Client.SendTo(a, a.Length, SocketFlags.None, serviceIp);
}
else
{
var res = Encoding.Default.GetString(bRecv);
Console.WriteLine(res);
}
}
}
本篇是初作,新人不易,多多支持! 【若转载请注明出处】