监听UDP接收指令,实现再次启动则弹出已启动的

This commit is contained in:
ChsBuffer
2020-08-06 05:50:43 +08:00
parent 0e2d3b63b7
commit d447f963df
5 changed files with 110 additions and 2 deletions

View File

@@ -51,6 +51,7 @@ namespace Netch.Forms
private void MainForm_Load(object sender, EventArgs e)
{
OnlyInstance.Called += OnCalled;
// 计算 ComboBox绘制 目标宽度
_eWidth = ServerComboBox.Width / 10;
@@ -107,6 +108,21 @@ namespace Netch.Forms
});
}
private void OnCalled(object sender, OnlyInstance.Commands e)
{
switch (e)
{
case OnlyInstance.Commands.Show:
NotifyIcon_MouseDoubleClick(null, null);
break;
case OnlyInstance.Commands.Exit:
Exit(true);
break;
default:
throw new ArgumentOutOfRangeException(nameof(e), e, null);
}
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{

View File

@@ -124,6 +124,11 @@ namespace Netch.Models
/// </summary>
public int RedirectorTCPPort = 3901;
/// <summary>
/// UDP Socket 占用端口
/// </summary>
public int UDPSocketPort = 18291;
/// <summary>
/// HTTP 和 Socks5 本地代理地址
/// </summary>

View File

@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Netch.Controllers;
using Netch.Forms;
@@ -65,13 +66,14 @@ namespace Netch
// 检查是否已经运行
if (!mutex.WaitOne(0, false))
{
// 弹出提示
MessageBoxX.Show(i18N.Translate("Netch is already running"));
OnlyInstance.Send(OnlyInstance.Commands.Show);
// 退出进程
Environment.Exit(1);
}
Task.Run(OnlyInstance.Server);
// 绑定错误捕获
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += Application_OnException;

View File

@@ -0,0 +1,71 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace Netch.Utils
{
public class OnlyInstance
{
public enum Commands
{
Show,
Exit
}
public static event EventHandler<Commands> Called;
private static void OnCalled(Commands e)
{
Called?.Invoke(null, e);
}
public static async void Server()
{
try
{
if (PortHelper.PortInUse(Global.Settings.UDPSocketPort))
{
Global.Settings.UDPSocketPort = PortHelper.GetAvailablePort();
Configuration.Save();
}
var data = new byte[1024];
var newsock = new UdpClient(new IPEndPoint(IPAddress.Loopback, Global.Settings.UDPSocketPort));
while (true)
{
var result = await newsock.ReceiveAsync();
data = result.Buffer;
if (Enum.TryParse<Commands>(Encoding.ASCII.GetString(data, 0, data.Length), out var command))
{
OnCalled(command);
}
}
}
catch (Exception e)
{
Logging.Error(e.ToString());
}
}
public static async void Send(Commands command)
{
try
{
using (var udpClient = new UdpClient(Global.Settings.UDPSocketPort))
{
udpClient.Connect(IPAddress.Loopback, Global.Settings.UDPSocketPort);
var sendBytes = Encoding.ASCII.GetBytes(command.ToString());
await udpClient.SendAsync(sendBytes, sendBytes.Length);
udpClient.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}

View File

@@ -111,6 +111,20 @@ namespace Netch.Utils
return isPortExcluded && (isTcpUsed || isUdpUsed);
}
public static int GetAvailablePort()
{
for (var i = 0; i < 55535; i++)
{
var p = new Random().Next(10000, 65535);
if (!PortInUse(p))
{
return p;
}
}
throw new Exception("Cant Generate Available Port");
}
}
/// <summary>