BITKit/Src/Core/Net/LAN/UdpBasedLanBroadcaster.cs

140 lines
3.0 KiB
C#
Raw Normal View History

2023-10-06 23:43:19 +08:00
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace BITKit.Net.LAN
{
/// <summary>
/// 基于UDP的LAN广播
/// </summary>
public class UdpBasedLanBroadcaster : ILANBroadcaster
{
public int Port { get; set; }
public byte[] Buffer { get; set; } = StringHelper.GetBytes("Hello World");
private bool _isBroadcasting;
private bool _isListening;
2024-03-31 23:31:00 +08:00
private int head;
private int revHead;
private Thread _thread;
2023-10-06 23:43:19 +08:00
public UdpBasedLanBroadcaster()
{
}
2024-03-31 23:31:00 +08:00
public event Action<EndPoint, byte[]> OnReceive;
2023-10-06 23:43:19 +08:00
public void StartBroadcast()
{
_isBroadcasting = true;
2024-03-31 23:31:00 +08:00
_thread = new(Process)
2023-10-06 23:43:19 +08:00
{
IsBackground = true
};
2024-03-31 23:31:00 +08:00
_thread.Start();
2023-10-06 23:43:19 +08:00
BIT4Log.Log<ILANBroadcaster>($"开始广播端口{Port}");
}
public void StopBroadcast()
{
_isBroadcasting = false;
BIT4Log.Log<ILANBroadcaster>($"停止广播端口 {Port}");
}
public void StartListen()
{
2024-03-31 23:31:00 +08:00
if (_isListening) return;
2023-10-06 23:43:19 +08:00
_isListening = true;
2024-03-31 23:31:00 +08:00
_thread = new Thread(ReceiveThread)
2023-10-06 23:43:19 +08:00
{
IsBackground = true
};
2024-03-31 23:31:00 +08:00
_thread.Start();
2023-10-06 23:43:19 +08:00
BIT4Log.Log<ILANBroadcaster>($"开始监听端口:{Port}");
}
public void StopListen()
{
2024-03-31 23:31:00 +08:00
if (_isListening is false) return;
2023-10-06 23:43:19 +08:00
_isListening = false;
2024-03-31 23:31:00 +08:00
_thread?.Abort();
2023-10-06 23:43:19 +08:00
BIT4Log.Log<ILANBroadcaster>($"停止监听端口{Port}");
}
2024-03-31 23:31:00 +08:00
public void Process()
2023-10-06 23:43:19 +08:00
{
var udpClient = new UdpClient(new IPEndPoint(IPAddress.Any, 0));
var endpoint = new IPEndPoint(IPAddress.Broadcast, Port);
//其实 IPAddress.Broadcast 就是 255.255.255.255
//下面代码与上面有相同的作用
//IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("255.255.255.255"), 8080);
try
{
2024-03-31 23:31:00 +08:00
var tempBuffer = new byte[Buffer.Length + 1];
tempBuffer[0] = (byte)head++;
Buffer.CopyTo(tempBuffer, 1);
udpClient.Send(tempBuffer, tempBuffer.Length, endpoint);
Thread.Sleep(1000);
2023-10-06 23:43:19 +08:00
while (_isBroadcasting)
{
2024-03-31 23:31:00 +08:00
udpClient.Send(tempBuffer, tempBuffer.Length, endpoint);
2023-10-06 23:43:19 +08:00
Thread.Sleep(1000);
}
}
catch (Exception e)
{
BIT4Log.LogException(e);
}
udpClient.Dispose();
}
private void ReceiveThread()
{
try
{
var udpClient = new UdpClient(new IPEndPoint(IPAddress.Any, Port));
var endpoint = new IPEndPoint(IPAddress.Any, 0);
2024-03-31 23:31:00 +08:00
while (_isListening && BITApp.CancellationToken.IsCancellationRequested is false)
2023-10-06 23:43:19 +08:00
{
2024-03-31 23:31:00 +08:00
byte[] buf;
try
{
buf = udpClient.Receive(ref endpoint);
}
catch (ThreadAbortException)
{
udpClient.Dispose();
return;
}
var packageHead = buf[0];
if(packageHead<revHead)
continue;
revHead = packageHead;
buf = buf[1..];
2023-10-06 23:43:19 +08:00
if (OnReceive is not null)
2024-03-31 23:31:00 +08:00
OnReceive(endpoint, buf);
2023-10-06 23:43:19 +08:00
else
2024-03-31 23:31:00 +08:00
BIT4Log.Log<ILANBroadcaster>($"Receive From {endpoint}:\t{buf}");
2023-10-06 23:43:19 +08:00
Thread.Sleep(500);
}
2024-03-31 23:31:00 +08:00
udpClient.Dispose();
2023-10-06 23:43:19 +08:00
}
2024-03-31 23:31:00 +08:00
catch(ThreadAbortException){}
2023-10-06 23:43:19 +08:00
catch (Exception e)
{
BIT4Log.LogException(e);
}
}
2024-03-31 23:31:00 +08:00
public void Dispose()
{
StopBroadcast();
StopListen();
OnReceive = null;
}
2023-10-06 23:43:19 +08:00
}
}