140 lines
3.0 KiB
C#
140 lines
3.0 KiB
C#
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;
|
|
private int head;
|
|
private int revHead;
|
|
|
|
private Thread _thread;
|
|
|
|
public UdpBasedLanBroadcaster()
|
|
{
|
|
|
|
}
|
|
|
|
public event Action<EndPoint, byte[]> OnReceive;
|
|
|
|
public void StartBroadcast()
|
|
{
|
|
_isBroadcasting = true;
|
|
_thread = new(Process)
|
|
{
|
|
IsBackground = true
|
|
};
|
|
_thread.Start();
|
|
BIT4Log.Log<ILANBroadcaster>($"开始广播端口{Port}");
|
|
}
|
|
|
|
public void StopBroadcast()
|
|
{
|
|
_isBroadcasting = false;
|
|
BIT4Log.Log<ILANBroadcaster>($"停止广播端口 {Port}");
|
|
}
|
|
|
|
public void StartListen()
|
|
{
|
|
if (_isListening) return;
|
|
_isListening = true;
|
|
_thread = new Thread(ReceiveThread)
|
|
{
|
|
IsBackground = true
|
|
};
|
|
_thread.Start();
|
|
BIT4Log.Log<ILANBroadcaster>($"开始监听端口:{Port}");
|
|
}
|
|
public void StopListen()
|
|
{
|
|
if (_isListening is false) return;
|
|
_isListening = false;
|
|
_thread?.Abort();
|
|
BIT4Log.Log<ILANBroadcaster>($"停止监听端口{Port}");
|
|
}
|
|
|
|
public void Process()
|
|
{
|
|
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
|
|
{
|
|
var tempBuffer = new byte[Buffer.Length + 1];
|
|
tempBuffer[0] = (byte)head++;
|
|
Buffer.CopyTo(tempBuffer, 1);
|
|
udpClient.Send(tempBuffer, tempBuffer.Length, endpoint);
|
|
Thread.Sleep(1000);
|
|
while (_isBroadcasting)
|
|
{
|
|
udpClient.Send(tempBuffer, tempBuffer.Length, endpoint);
|
|
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);
|
|
while (_isListening && BITApp.CancellationToken.IsCancellationRequested is false)
|
|
{
|
|
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..];
|
|
if (OnReceive is not null)
|
|
OnReceive(endpoint, buf);
|
|
else
|
|
BIT4Log.Log<ILANBroadcaster>($"Receive From {endpoint}:\t{buf}");
|
|
Thread.Sleep(500);
|
|
}
|
|
udpClient.Dispose();
|
|
}
|
|
catch(ThreadAbortException){}
|
|
catch (Exception e)
|
|
{
|
|
BIT4Log.LogException(e);
|
|
}
|
|
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
StopBroadcast();
|
|
StopListen();
|
|
OnReceive = null;
|
|
}
|
|
}
|
|
} |