using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Net.Http; using System.Net.Sockets; using System.Text; using System.Text.Json; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows.Forms; using SF_Demo.Tools; namespace Go_Frp { public partial class Go_Frp : Form { // 添加字典用于存储 frpc 进程 private Dictionary frpcProcesses = new Dictionary(); JobManager jobManager = JobManager.Instance; public Go_Frp() { InitializeComponent(); } // Frp 类 public class Frp { public string host { get; set; } public string port { get; set; } public string token { get; set; } } // 确保窗口只触发一次 private bool isLoginShow = false; // 定时器字段 private System.Windows.Forms.Timer statusCheckTimer; // 地址信息 private string url = "http://192.168.177.1:8080/servers"; // 窗口启动时执行 protected override async void OnLoad(EventArgs e) { base.OnLoad(e); // 登录窗口 if (!isLoginShow) { isLoginShow = true; // 创建并显示窗口 using (Login login = new Login()) { login.ShowDialog(); } } // 服务器状态 // 立即执行一次 await CheckServerStatusAsync(); // 初始化定时 statusCheckTimer = new System.Windows.Forms.Timer(); statusCheckTimer.Interval = 5000; statusCheckTimer.Tick += async (sendier, args) => await CheckServerStatusAsync(); } // 连接按钮 private async void Connect_but_Click(object sender, EventArgs e) { try { // 获取数据 var data = await FetchFrpDataAsync(url); // 程序路径 string appPath = "../../Frpc/frpc.exe"; // 日志目录 string logDirPath = "../../Frpc/log"; // 检查并创建日志目录 if (!Directory.Exists(logDirPath)) { Directory.CreateDirectory(logDirPath); } // 服务器信息 string local_host = Host_box.Text; string local_port = Port_box.Text; string local_domain = Domain_box.Text; // 进程启动 foreach (var server in data) { try { // 创建日志文件 string logFile = Path.Combine(logDirPath, $"{server.Key}.log"); // 启动参数 string arguments = $"http " + $"-s {server.Value.host} " + $"-P {server.Value.port} " + $"-t {server.Value.token} " + $"-i {local_host} " + $"-l {local_port} " + $"-d \"{local_domain}\" " + $"-n {server.Key}"; // 记录启动命令到日志中 File.AppendAllText(logFile, $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 启动命令: ./frpc.exe {arguments}\n"); // 创建启动 ProcessStartInfo startinfo = new ProcessStartInfo { FileName = appPath, //FileName = "cmd.exe", Arguments = arguments, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, }; // 创建并启动进程 Process frpcProcess = new Process { StartInfo = startinfo, EnableRaisingEvents = true }; // 设置输出事件处理 frpcProcess.OutputDataReceived += (s, args) => { if (!string.IsNullOrEmpty(args.Data)) { string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); string cleanData = RemoveAnsiEscapeCodes(args.Data); string logMessage = $"[{timestamp}] {cleanData}"; try { // 写入日志文件 File.AppendAllText(logFile, logMessage + Environment.NewLine); // 更新显示 this.Invoke((MethodInvoker)delegate { if (server.Key == "Frp1") { Server_Log1.AppendText(logMessage + Environment.NewLine); Server_Log1.SelectionStart = Server_Log1.Text.Length; Server_Log1.ScrollToCaret(); } else if (server.Key == "Frp2") { Server_Log2.AppendText(logMessage + Environment.NewLine); Server_Log2.SelectionStart = Server_Log2.Text.Length; Server_Log2.ScrollToCaret(); } }); } catch (Exception ex) { MessageBox.Show($"处理输出时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } }; // 错误输出处理 frpcProcess.ErrorDataReceived += (s, args) => { if (!string.IsNullOrEmpty(args.Data)) { string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); string cleanData = RemoveAnsiEscapeCodes(args.Data); string logMessage = $"[{timestamp}] ERROR: {cleanData}"; try { File.AppendAllText(logFile, logMessage + Environment.NewLine); this.Invoke((MethodInvoker)delegate { if (server.Key == "Frp1") { Server_Log1.AppendText(logMessage + Environment.NewLine); Server_Log1.SelectionStart = Server_Log1.Text.Length; Server_Log1.ScrollToCaret(); } else if (server.Key == "Frp2") { Server_Log2.AppendText(logMessage + Environment.NewLine); Server_Log2.SelectionStart = Server_Log2.Text.Length; Server_Log2.ScrollToCaret(); } }); } catch (Exception ex) { MessageBox.Show($"处理错误输出时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } }; // 启动进程 if (!frpcProcess.Start()) { throw new Exception("进程启动失败"); } // 添加到作业管理器 jobManager.AddProcessToJob(frpcProcess); // 开始异步读取 frpcProcess.BeginOutputReadLine(); frpcProcess.BeginErrorReadLine(); // 存储进程引用 frpcProcesses[server.Key] = frpcProcess; } catch (Exception ex) { MessageBox.Show($"启动 {server.Key} 失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } catch (Exception ex) { MessageBox.Show($"连接失败: {ex.Message}\n{ex.StackTrace}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } // 获取数据 private async Task> FetchFrpDataAsync(string url) { using (HttpClient client = new HttpClient()) { HttpResponseMessage response = await client.GetAsync(url); response.EnsureSuccessStatusCode(); string jsonResponse = await response.Content.ReadAsStringAsync(); // 动态反序列化 JSON 数据 return JsonSerializer.Deserialize>(jsonResponse); } } // 检查服务器状态 private async Task CheckServerStatusAsync() { var data = await FetchFrpDataAsync(url); // 修改服务器状态 foreach (var server in data) { string ip = server.Value.host; string port = server.Value.port; bool isConnected = await CheckServerConnectionAsync(ip, port); if (server.Key == "Frp1") { if (isConnected) { Server_connect1.Text = "在线"; Server_connect1.ForeColor = Color.Lime; } else { Server_connect1.Text = "离线"; Server_connect1.ForeColor = Color.Red; } } else if (server.Key == "Frp2") { if (isConnected) { Server_connect2.Text = "在线"; Server_connect2.ForeColor = Color.Lime; } else { Server_connect2.Text = "离线"; Server_connect2.ForeColor = Color.Red; } } } } // 检查服务器连接 private async Task CheckServerConnectionAsync(string ip, string port) { try { if (!int.TryParse(port, out int portNumber) || portNumber < 1 || portNumber > 65535) { // 如果端口无效(非数字或超出有效范围),返回 false return false; } using (TcpClient tcpClient = new TcpClient()) { // 尝试连接服务器 var connectTask = tcpClient.ConnectAsync(ip, portNumber); var timeoutTask = Task.Delay(3000); // 设置超时时间 if (await Task.WhenAny(connectTask, timeoutTask) == connectTask) { return tcpClient.Connected; } else { return false; // 超时未连接 } } } catch { return false; } } // 去除 ANSI 转义序列函数 private string RemoveAnsiEscapeCodes(string input) { // 正则表达式匹配 ANSI 转义序列 string pattern = @"\x1b\[[0-9;]*[a-zA-Z]"; return Regex.Replace(input, pattern, string.Empty); } } }