编辑
2025-11-23
C#
00

目录

💡 为什么要自己开发HTTP代理服务器?
🔍 常见应用场景分析
🛠️ 核心技术方案选型
🔥 基础HTTP代理服务器实现
💻 完整可运行代码
🎯 使用说明
⚠️ 常见坑点提醒
🔧 方案二:带请求监控的高级代理服务器
📊 功能增强点
💻 核心监控代码实现
🎯 实际应用场景
📱 场景一:开发环境网络调试
🏢 场景二:企业网络管控
📊 场景三:性能分析和优化
💡 高级技巧与最佳实践
🔧 性能优化建议
🛡️ 安全性考虑
📈 扩展性设计
🎯 总结
🔑 三个核心要点
💬 互动话题

你是否遇到过这样的开发痛点:内网环境无法访问外部API,需要通过代理进行调试?或者需要监控团队应用的HTTP请求流量?最近在.NET技术群里,很多开发者都在讨论一个共同问题:"如何快速实现一个灵活可控的HTTP代理服务器?"

据不完全统计,超过70%的企业级应用都需要代理服务器来处理网络请求,但市面上的代理工具要么功能单一,要么配置复杂。今天就带你用C#从零开始,10分钟内搭建一个功能完整的HTTP代理服务器,让你彻底掌握网络代理的核心原理和实现技巧!

💡 为什么要自己开发HTTP代理服务器?

🔍 常见应用场景分析

在实际C#开发中,我们经常遇到这些痛点:

1. 开发环境限制:内网环境无法直接访问外部API

2. 请求监控需求:需要记录和分析HTTP请求数据

3. 访问控制:对特定域名或IP进行过滤

4. 性能优化:缓存频繁请求的响应数据

5. 负载均衡:将请求分发到不同的后端服务器

🛠️ 核心技术方案选型

方案优势劣势适用场景
HttpListener简单易用功能有限轻量级代理
Socket编程性能最佳开发复杂高性能场景
ASP.NET Core功能丰富资源占用大企业级应用

本文采用HttpListener + Socket的混合方案,既保证了开发效率,又确保了核心功能的完整性。

🔥 基础HTTP代理服务器实现

💻 完整可运行代码

C#
using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; public class BasicHttpProxyServer { private readonly int _port; private TcpListener _listener; private bool _isRunning; public BasicHttpProxyServer(int port = 8888) { _port = port; } /// <summary> /// 启动代理服务器 /// </summary> public async Task StartAsync() { _listener = new TcpListener(IPAddress.Any, _port); _listener.Start(); _isRunning = true; Console.WriteLine($"🚀 HTTP代理服务器已启动,监听端口: {_port}"); Console.WriteLine($"📖 浏览器代理设置: 127.0.0.1:{_port}"); while (_isRunning) { try { var client = await _listener.AcceptTcpClientAsync(); // 异步处理每个客户端连接,避免阻塞 _ = Task.Run(() => HandleClientAsync(client)); } catch (Exception ex) { Console.WriteLine($"❌ 接受连接时出错: {ex.Message}"); } } } /// <summary> /// 处理客户端请求的核心方法 /// </summary> private async Task HandleClientAsync(TcpClient client) { NetworkStream clientStream = null; try { clientStream = client.GetStream(); // 读取HTTP请求头 var requestData = await ReadHttpRequestAsync(clientStream); if (string.IsNullOrEmpty(requestData)) return; Console.WriteLine($"📥 接收请求: {requestData.Split('\n')[0]}"); // 解析请求信息 var requestInfo = ParseHttpRequest(requestData); if (requestInfo == null) return; // 处理CONNECT方法(HTTPS隧道) if (requestInfo.Method.Equals("CONNECT", StringComparison.OrdinalIgnoreCase)) { await HandleHttpsConnectAsync(clientStream, requestInfo); } else { // 处理普通HTTP请求 await HandleHttpRequestAsync(clientStream, requestInfo, requestData); } } catch (Exception ex) { Console.WriteLine($"❌ 处理客户端请求时出错: {ex.Message}"); } finally { clientStream?.Close(); client?.Close(); } } /// <summary> /// 读取HTTP请求数据 /// </summary> private async Task<string> ReadHttpRequestAsync(NetworkStream stream) { var buffer = new byte[4096]; var requestBuilder = new StringBuilder(); try { // 设置读取超时时间 stream.ReadTimeout = 5000; while (true) { var bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length); if (bytesRead == 0) break; var data = Encoding.UTF8.GetString(buffer, 0, bytesRead); requestBuilder.Append(data); // 检查是否读取完整的HTTP头部 if (requestBuilder.ToString().Contains("\r\n\r\n")) break; } } catch (Exception ex) { Console.WriteLine($"⚠️ 读取请求数据时出错: {ex.Message}"); return null; } return requestBuilder.ToString(); } /// <summary> /// 解析HTTP请求信息 /// </summary> private RequestInfo ParseHttpRequest(string request) { try { var lines = request.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); if (lines.Length == 0) return null; var requestLine = lines[0].Split(' '); if (requestLine.Length < 3) return null; var method = requestLine[0]; var url = requestLine[1]; var version = requestLine[2]; // 解析目标主机和端口 string host = "localhost"; int port = 80; if (method.Equals("CONNECT", StringComparison.OrdinalIgnoreCase)) { // CONNECT方法的URL格式: host:port var parts = url.Split(':'); host = parts[0]; port = parts.Length > 1 ? int.Parse(parts[1]) : 443; } else { // 从Host头部获取主机信息 foreach (var line in lines) { if (line.StartsWith("Host:", StringComparison.OrdinalIgnoreCase)) { var hostValue = line.Substring(5).Trim(); var hostParts = hostValue.Split(':'); host = hostParts[0]; port = hostParts.Length > 1 ? int.Parse(hostParts[1]) : 80; break; } } } return new RequestInfo { Method = method, Url = url, Version = version, Host = host, Port = port }; } catch (Exception ex) { Console.WriteLine($"❌ 解析请求时出错: {ex.Message}"); return null; } } /// <summary> /// 处理HTTPS CONNECT请求(建立隧道) /// </summary> private async Task HandleHttpsConnectAsync(NetworkStream clientStream, RequestInfo requestInfo) { TcpClient targetClient = null; NetworkStream targetStream = null; try { // 连接目标服务器 targetClient = new TcpClient(); await targetClient.ConnectAsync(requestInfo.Host, requestInfo.Port); targetStream = targetClient.GetStream(); // 向客户端发送连接成功响应 var response = "HTTP/1.1 200 Connection Established\r\n\r\n"; var responseBytes = Encoding.UTF8.GetBytes(response); await clientStream.WriteAsync(responseBytes, 0, responseBytes.Length); Console.WriteLine($"🔐 HTTPS隧道已建立: {requestInfo.Host}:{requestInfo.Port}"); // 开始双向数据转发 var task1 = ForwardDataAsync(clientStream, targetStream, "客户端->服务器"); var task2 = ForwardDataAsync(targetStream, clientStream, "服务器->客户端"); await Task.WhenAny(task1, task2); } catch (Exception ex) { Console.WriteLine($"❌ HTTPS隧道建立失败: {ex.Message}"); } finally { targetStream?.Close(); targetClient?.Close(); } } /// <summary> /// 数据转发方法(用于HTTPS隧道) /// </summary> private async Task ForwardDataAsync(NetworkStream from, NetworkStream to, string direction) { var buffer = new byte[4096]; try { while (true) { var bytesRead = await from.ReadAsync(buffer, 0, buffer.Length); if (bytesRead == 0) break; await to.WriteAsync(buffer, 0, bytesRead); Console.WriteLine($"📡 数据转发 {direction}: {bytesRead} 字节"); } } catch (Exception ex) { Console.WriteLine($"⚠️ 数据转发中断 {direction}: {ex.Message}"); } } /// <summary> /// 停止代理服务器 /// </summary> public void Stop() { _isRunning = false; _listener?.Stop(); Console.WriteLine("🛑 HTTP代理服务器已停止"); } } /// <summary> /// 请求信息数据结构 /// </summary> public class RequestInfo { public string Method { get; set; } public string Url { get; set; } public string Version { get; set; } public string Host { get; set; } public int Port { get; set; } } /// <summary> /// 程序入口点 /// </summary> class Program { static async Task Main(string[] args) { var proxy = new BasicHttpProxyServer(8888); Console.WriteLine("按 Ctrl+C 停止服务器"); Console.CancelKeyPress += (sender, e) => { e.Cancel = true; proxy.Stop(); Environment.Exit(0); }; await proxy.StartAsync(); } }

🎯 使用说明

1. 编译运行:将代码保存为.cs文件,使用dotnet run启动

2. 浏览器设置:将浏览器代理设置为127.0.0.1:8888

3. 测试验证:访问任意网站,查看控制台输出

⚠️ 常见坑点提醒

  • 端口占用:确保选择的端口未被其他程序占用
  • 防火墙设置:可能需要添加防火墙规则允许程序监听端口
  • 超时处理:网络超时会导致连接挂起,代码中已添加超时控制

🔧 方案二:带请求监控的高级代理服务器

📊 功能增强点

在基础版本的基础上,我们来实现一个企业级的高级代理服务器,新增以下核心功能:

1. 请求监控:记录每个请求的详细信息和响应时间

2. 域名过滤:支持黑名单机制,自动阻止恶意域名访问

3. 统计分析:定时输出代理服务器运行统计

4. 日志导出:支持将请求日志导出为JSON格式

5. 性能监控:实时监控数据传输量和响应时间

💻 核心监控代码实现

C#
using System.Net.Sockets; using System.Net; using System.Text; using System.Collections.Concurrent; using System.Text.Json; namespace AppBasicHttpProxyServer { /// <summary> /// 带请求监控的高级代理服务器 /// </summary> public class AdvancedHttpProxyServer { private readonly int _port; private TcpListener _listener; private bool _isRunning; // 请求监控和统计 private readonly ConcurrentQueue<RequestLog> _requestLogs; private readonly ConcurrentDictionary<string, DomainStats> _domainStats; private readonly object _statsLock = new object(); // 配置选项 private readonly ProxyConfig _config; public AdvancedHttpProxyServer(int port = 8888, ProxyConfig config = null) { _port = port; _requestLogs = new ConcurrentQueue<RequestLog>(); _domainStats = new ConcurrentDictionary<string, DomainStats>(); _config = config ?? new ProxyConfig(); // 启动监控任务 if (_config.EnableMonitoring) { _ = Task.Run(MonitoringTaskAsync); } // 启动日志清理任务 if (_config.EnableLogCleanup) { _ = Task.Run(LogCleanupTaskAsync); } } /// <summary> /// 启动代理服务器 /// </summary> public async Task StartAsync() { _listener = new TcpListener(IPAddress.Any, _port); _listener.Start(); _isRunning = true; Console.WriteLine("🚀 高级HTTP代理服务器已启动"); Console.WriteLine($"📡 监听端口: {_port}"); Console.WriteLine($"📊 监控功能: {(_config.EnableMonitoring ? "启用" : "禁用")}"); Console.WriteLine($"📝 日志记录: {(_config.EnableLogging ? "启用" : "禁用")}"); Console.WriteLine($"🚫 域名过滤: {(_config.BlockedDomains.Any() ? "启用" : "禁用")}"); Console.WriteLine($"📖 浏览器代理设置: 127.0.0.1:{_port}"); Console.WriteLine(new string('=', 50)); while (_isRunning) { try { var client = await _listener.AcceptTcpClientAsync(); // 异步处理每个客户端连接,避免阻塞 _ = Task.Run(() => HandleClientAsync(client)); } catch (Exception ex) when (_isRunning) { Console.WriteLine($"❌ 接受连接时出错: {ex.Message}"); } } } /// <summary> /// 处理客户端请求的核心方法 /// </summary> private async Task HandleClientAsync(TcpClient client) { NetworkStream clientStream = null; RequestLog requestLog = new RequestLog { Timestamp = DateTime.Now, ClientEndPoint = client.Client.RemoteEndPoint?.ToString() }; try { clientStream = client.GetStream(); // 设置超时时间 client.ReceiveTimeout = _config.ReceiveTimeout; client.SendTimeout = _config.SendTimeout; // 读取HTTP请求头 var requestData = await ReadHttpRequestAsync(clientStream); if (string.IsNullOrEmpty(requestData)) { requestLog.Status = "Failed - Empty Request"; return; } // 解析请求信息 var requestInfo = ParseHttpRequest(requestData); if (requestInfo == null) { requestLog.Status = "Failed - Parse Error"; return; } // 更新请求日志 requestLog.Method = requestInfo.Method; requestLog.Host = requestInfo.Host; requestLog.Url = requestInfo.Url; requestLog.Port = requestInfo.Port; // 检查域名过滤 if (IsDomainBlocked(requestInfo.Host)) { await SendBlockedResponse(clientStream); requestLog.Status = "Blocked"; requestLog.BytesTransferred = 0; Console.WriteLine($"🚫 请求被阻止: {requestInfo.Host}"); return; } Console.WriteLine($"📥 [{DateTime.Now:HH:mm:ss}] {requestInfo.Method} {requestInfo.Host}:{requestInfo.Port}"); // 处理请求 if (requestInfo.Method.Equals("CONNECT", StringComparison.OrdinalIgnoreCase)) { await HandleHttpsConnectAsync(clientStream, requestInfo, requestLog); } else { await HandleHttpRequestAsync(clientStream, requestInfo, requestData, requestLog); } } catch (Exception ex) { Console.WriteLine($"❌ 处理客户端请求时出错: {ex.Message}"); requestLog.Status = $"Error - {ex.Message}"; } finally { requestLog.EndTime = DateTime.Now; requestLog.Duration = (requestLog.EndTime - requestLog.Timestamp).TotalMilliseconds; // 记录请求日志 if (_config.EnableLogging) { _requestLogs.Enqueue(requestLog); } // 更新域名统计 UpdateDomainStats(requestLog); clientStream?.Close(); client?.Close(); } } /// <summary> /// 读取HTTP请求数据 /// </summary> private async Task<string> ReadHttpRequestAsync(NetworkStream stream) { var buffer = new byte[4096]; var requestBuilder = new StringBuilder(); try { stream.ReadTimeout = _config.ReceiveTimeout; while (true) { var bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length); if (bytesRead == 0) break; var data = Encoding.UTF8.GetString(buffer, 0, bytesRead); requestBuilder.Append(data); // 检查是否读取完整的HTTP头部 if (requestBuilder.ToString().Contains("\r\n\r\n")) break; } } catch (Exception ex) { Console.WriteLine($"⚠️ 读取请求数据时出错: {ex.Message}"); return null; } return requestBuilder.ToString(); } /// <summary> /// 解析HTTP请求信息 /// </summary> private RequestInfo ParseHttpRequest(string request) { try { var lines = request.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); if (lines.Length == 0) return null; var requestLine = lines[0].Split(' '); if (requestLine.Length < 3) return null; var method = requestLine[0]; var url = requestLine[1]; var version = requestLine[2]; // 解析目标主机和端口 string host = "localhost"; int port = 80; if (method.Equals("CONNECT", StringComparison.OrdinalIgnoreCase)) { // CONNECT方法的URL格式: host:port var parts = url.Split(':'); host = parts[0]; port = parts.Length > 1 ? int.Parse(parts[1]) : 443; } else { // 从Host头部获取主机信息 foreach (var line in lines) { if (line.StartsWith("Host:", StringComparison.OrdinalIgnoreCase)) { var hostValue = line.Substring(5).Trim(); var hostParts = hostValue.Split(':'); host = hostParts[0]; port = hostParts.Length > 1 ? int.Parse(hostParts[1]) : 80; break; } } } return new RequestInfo { Method = method, Url = url, Version = version, Host = host, Port = port }; } catch (Exception ex) { Console.WriteLine($"❌ 解析请求时出错: {ex.Message}"); return null; } } /// <summary> /// 处理HTTPS CONNECT请求(建立隧道) /// </summary> private async Task HandleHttpsConnectAsync(NetworkStream clientStream, RequestInfo requestInfo, RequestLog requestLog) { TcpClient targetClient = null; NetworkStream targetStream = null; try { // 连接目标服务器 targetClient = new TcpClient(); await targetClient.ConnectAsync(requestInfo.Host, requestInfo.Port); targetStream = targetClient.GetStream(); // 向客户端发送连接成功响应 var response = "HTTP/1.1 200 Connection Established\r\n\r\n"; var responseBytes = Encoding.UTF8.GetBytes(response); await clientStream.WriteAsync(responseBytes, 0, responseBytes.Length); Console.WriteLine($"🔐 HTTPS隧道已建立: {requestInfo.Host}:{requestInfo.Port}"); requestLog.Status = "Connected"; // 开始双向数据转发 var task1 = ForwardDataAsync(clientStream, targetStream, requestLog, "客户端->服务器"); var task2 = ForwardDataAsync(targetStream, clientStream, requestLog, "服务器->客户端"); await Task.WhenAny(task1, task2); requestLog.Status = "Completed"; } catch (Exception ex) { Console.WriteLine($"❌ HTTPS隧道建立失败: {ex.Message}"); requestLog.Status = $"Failed - {ex.Message}"; } finally { targetStream?.Close(); targetClient?.Close(); } } /// <summary> /// 处理普通HTTP请求 /// </summary> private async Task HandleHttpRequestAsync(NetworkStream clientStream, RequestInfo requestInfo, string requestData, RequestLog requestLog) { TcpClient targetClient = null; NetworkStream targetStream = null; try { // 连接目标服务器 targetClient = new TcpClient(); await targetClient.ConnectAsync(requestInfo.Host, requestInfo.Port); targetStream = targetClient.GetStream(); // 转发请求到目标服务器 var requestBytes = Encoding.UTF8.GetBytes(requestData); await targetStream.WriteAsync(requestBytes, 0, requestBytes.Length); // 读取并转发响应 var buffer = new byte[4096]; while (true) { var bytesRead = await targetStream.ReadAsync(buffer, 0, buffer.Length); if (bytesRead == 0) break; await clientStream.WriteAsync(buffer, 0, bytesRead); requestLog.BytesTransferred += bytesRead; } requestLog.Status = "Completed"; Console.WriteLine($"✅ HTTP请求完成: {requestInfo.Host} ({requestLog.BytesTransferred} 字节)"); } catch (Exception ex) { Console.WriteLine($"❌ HTTP请求处理失败: {ex.Message}"); requestLog.Status = $"Failed - {ex.Message}"; } finally { targetStream?.Close(); targetClient?.Close(); } } /// <summary> /// 数据转发方法(用于HTTPS隧道) /// </summary> private async Task ForwardDataAsync(NetworkStream from, NetworkStream to, RequestLog requestLog, string direction) { var buffer = new byte[4096]; try { while (true) { var bytesRead = await from.ReadAsync(buffer, 0, buffer.Length); if (bytesRead == 0) break; await to.WriteAsync(buffer, 0, bytesRead); lock (requestLog) { requestLog.BytesTransferred += bytesRead; } if (_config.EnableVerboseLogging) { Console.WriteLine($"📡 数据转发 {direction}: {bytesRead} 字节"); } } } catch (Exception ex) { if (_config.EnableVerboseLogging) { Console.WriteLine($"⚠️ 数据转发中断 {direction}: {ex.Message}"); } } } /// <summary> /// 检查域名是否被阻止 /// </summary> private bool IsDomainBlocked(string host) { return _config.BlockedDomains.Any(blocked => host.Equals(blocked, StringComparison.OrdinalIgnoreCase) || host.EndsWith("." + blocked, StringComparison.OrdinalIgnoreCase)); } /// <summary> /// 发送阻止响应 /// </summary> private async Task SendBlockedResponse(NetworkStream stream) { var response = "HTTP/1.1 403 Forbidden\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 47\r\n" + "\r\n" + "<html><body><h1>Access Blocked</h1></body></html>"; var responseBytes = Encoding.UTF8.GetBytes(response); await stream.WriteAsync(responseBytes, 0, responseBytes.Length); } /// <summary> /// 更新域名统计 /// </summary> private void UpdateDomainStats(RequestLog requestLog) { if (string.IsNullOrEmpty(requestLog.Host)) return; _domainStats.AddOrUpdate(requestLog.Host, new DomainStats { RequestCount = 1, TotalBytes = requestLog.BytesTransferred, LastAccess = requestLog.Timestamp }, (key, existing) => { existing.RequestCount++; existing.TotalBytes += requestLog.BytesTransferred; existing.LastAccess = requestLog.Timestamp; return existing; }); } /// <summary> /// 监控任务 /// </summary> private async Task MonitoringTaskAsync() { while (_isRunning) { await Task.Delay(_config.MonitoringInterval); if (_config.EnableMonitoring) { DisplayStatistics(); } } } /// <summary> /// 显示统计信息 /// </summary> private void DisplayStatistics() { Console.WriteLine("\n" + "=".PadRight(60, '=')); Console.WriteLine("📊 代理服务器统计信息"); Console.WriteLine("=".PadRight(60, '=')); var now = DateTime.Now; var recentLogs = _requestLogs.Where(log => (now - log.Timestamp).TotalMinutes <= _config.StatisticsTimeWindow).ToList(); Console.WriteLine($"🕒 统计时间窗口: {_config.StatisticsTimeWindow} 分钟"); Console.WriteLine($"📈 总请求数: {recentLogs.Count}"); Console.WriteLine($"✅ 成功请求: {recentLogs.Count(l => l.Status == "Completed")}"); Console.WriteLine($"❌ 失败请求: {recentLogs.Count(l => l.Status.StartsWith("Failed"))}"); Console.WriteLine($"🚫 阻止请求: {recentLogs.Count(l => l.Status == "Blocked")}"); if (recentLogs.Any()) { Console.WriteLine($"📊 平均响应时间: {recentLogs.Average(l => l.Duration):F2} ms"); Console.WriteLine($"📦 总传输数据: {FormatBytes(recentLogs.Sum(l => l.BytesTransferred))}"); } // 显示热门域名 var topDomains = _domainStats .Where(kvp => (now - kvp.Value.LastAccess).TotalMinutes <= _config.StatisticsTimeWindow) .OrderByDescending(kvp => kvp.Value.RequestCount) .Take(5) .ToList(); if (topDomains.Any()) { Console.WriteLine("\n🔥 热门域名 (Top 5):"); foreach (var domain in topDomains) { Console.WriteLine($" {domain.Key}: {domain.Value.RequestCount} 次请求, {FormatBytes(domain.Value.TotalBytes)}"); } } Console.WriteLine("=".PadRight(60, '=') + "\n"); } /// <summary> /// 日志清理任务 /// </summary> private async Task LogCleanupTaskAsync() { while (_isRunning) { await Task.Delay(_config.LogCleanupInterval); var cutoffTime = DateTime.Now.AddHours(-_config.LogRetentionHours); var logsToKeep = new ConcurrentQueue<RequestLog>(); while (_requestLogs.TryDequeue(out var log)) { if (log.Timestamp > cutoffTime) { logsToKeep.Enqueue(log); } } // 将保留的日志放回队列 while (logsToKeep.TryDequeue(out var log)) { _requestLogs.Enqueue(log); } if (_config.EnableVerboseLogging) { Console.WriteLine($"🧹 日志清理完成,保留 {_requestLogs.Count} 条日志"); } } } /// <summary> /// 格式化字节数 /// </summary> private string FormatBytes(long bytes) { string[] sizes = { "B", "KB", "MB", "GB" }; double len = bytes; int order = 0; while (len >= 1024 && order < sizes.Length - 1) { order++; len = len / 1024; } return $"{len:0.##} {sizes[order]}"; } /// <summary> /// 获取统计信息JSON /// </summary> public string GetStatisticsJson() { var now = DateTime.Now; var recentLogs = _requestLogs.Where(log => (now - log.Timestamp).TotalMinutes <= _config.StatisticsTimeWindow).ToList(); var stats = new { Timestamp = now, TimeWindow = _config.StatisticsTimeWindow, TotalRequests = recentLogs.Count, SuccessfulRequests = recentLogs.Count(l => l.Status == "Completed"), FailedRequests = recentLogs.Count(l => l.Status.StartsWith("Failed")), BlockedRequests = recentLogs.Count(l => l.Status == "Blocked"), AverageResponseTime = recentLogs.Any() ? recentLogs.Average(l => l.Duration) : 0, TotalBytesTransferred = recentLogs.Sum(l => l.BytesTransferred), TopDomains = _domainStats .Where(kvp => (now - kvp.Value.LastAccess).TotalMinutes <= _config.StatisticsTimeWindow) .OrderByDescending(kvp => kvp.Value.RequestCount) .Take(10) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value) }; return JsonSerializer.Serialize(stats, new JsonSerializerOptions { WriteIndented = true }); } /// <summary> /// 停止代理服务器 /// </summary> public void Stop() { _isRunning = false; _listener?.Stop(); Console.WriteLine("🛑 高级HTTP代理服务器已停止"); } } /// <summary> /// 代理配置类 /// </summary> public class ProxyConfig { public bool EnableMonitoring { get; set; } = true; public bool EnableLogging { get; set; } = true; public bool EnableVerboseLogging { get; set; } = false; public bool EnableLogCleanup { get; set; } = true; public int MonitoringInterval { get; set; } = 30000; // 30秒 public int StatisticsTimeWindow { get; set; } = 60; // 60分钟 public int LogCleanupInterval { get; set; } = 3600000; // 1小时 public int LogRetentionHours { get; set; } = 24; // 24小时 public int ReceiveTimeout { get; set; } = 30000; // 30秒 public int SendTimeout { get; set; } = 30000; // 30秒 public HashSet<string> BlockedDomains { get; set; } = new HashSet<string>(); } /// <summary> /// 请求日志记录 /// </summary> public class RequestLog { public DateTime Timestamp { get; set; } public DateTime EndTime { get; set; } public double Duration { get; set; } public string ClientEndPoint { get; set; } public string Method { get; set; } public string Host { get; set; } public string Url { get; set; } public int Port { get; set; } public string Status { get; set; } public long BytesTransferred { get; set; } } /// <summary> /// 域名统计信息 /// </summary> public class DomainStats { public int RequestCount { get; set; } public long TotalBytes { get; set; } public DateTime LastAccess { get; set; } } /// <summary> /// 请求信息数据结构 /// </summary> public class RequestInfo { public string Method { get; set; } public string Url { get; set; } public string Version { get; set; } public string Host { get; set; } public int Port { get; set; } } /// <summary> /// 程序入口点 /// </summary> class Program { static async Task Main(string[] args) { Console.OutputEncoding = Encoding.UTF8; // 配置代理服务器 var config = new ProxyConfig { EnableMonitoring = true, EnableLogging = true, EnableVerboseLogging = false, // 设置为true可查看详细数据转发日志 MonitoringInterval = 30000, // 30秒显示一次统计 StatisticsTimeWindow = 60, // 统计过去60分钟的数据 // 添加一些被阻止的域名示例 BlockedDomains = new HashSet<string> { "malicious-site.com", "blocked-domain.net" } }; var proxy = new AdvancedHttpProxyServer(8888, config); // 设置控制台事件处理 Console.CancelKeyPress += (sender, e) => { e.Cancel = true; Console.WriteLine("\n正在停止服务器..."); proxy.Stop(); Environment.Exit(0); }; // 启动额外的控制台命令处理 _ = Task.Run(() => HandleConsoleCommands(proxy)); // 启动代理服务器 await proxy.StartAsync(); } /// <summary> /// 处理控制台命令 /// </summary> static async Task HandleConsoleCommands(AdvancedHttpProxyServer proxy) { Console.WriteLine("\n可用命令:"); Console.WriteLine(" stats - 显示当前统计信息"); Console.WriteLine(" json - 输出JSON格式统计信息"); Console.WriteLine(" quit - 退出程序"); Console.WriteLine("按 Ctrl+C 或输入 'quit' 停止服务器\n"); while (true) { try { var command = Console.ReadLine()?.Trim().ToLower(); switch (command) { case "stats": // 这里可以调用显示统计的方法 Console.WriteLine("📊 手动请求统计信息显示"); break; case "json": Console.WriteLine(proxy.GetStatisticsJson()); break; case "quit": case "exit": proxy.Stop(); Environment.Exit(0); break; case "help": Console.WriteLine("可用命令: stats, json, quit, help"); break; default: if (!string.IsNullOrEmpty(command)) { Console.WriteLine($"未知命令: {command}. 输入 'help' 查看可用命令"); } break; } } catch (Exception ex) { Console.WriteLine($"命令处理错误: {ex.Message}"); } } } } }

image.png

🎯 实际应用场景

📱 场景一:开发环境网络调试

C#
// 启动代理服务器进行API调试 var proxy = new AdvancedHttpProxyServer(8888); await proxy.StartAsync();

适用情况

  • 内网环境需要访问外部API
  • 需要监控应用的网络请求
  • 调试网络相关问题

🏢 场景二:企业网络管控

C#
// 配置企业级代理,添加访问控制 var proxy = new AdvancedHttpProxyServer(3128); proxy.AddBlockedDomain("social-media.com"); proxy.AddBlockedDomain("video-streaming.com"); await proxy.StartAsync();

适用情况

  • 企业内网访问控制
  • 员工上网行为监控
  • 恶意网站拦截

📊 场景三:性能分析和优化

C#
// 运行一段时间后导出分析数据 await proxy.ExportLogsAsync("network_analysis.json");

适用情况

  • 网络性能分析
  • 用户行为分析
  • 系统优化决策支持

💡 高级技巧与最佳实践

🔧 性能优化建议

1. 连接池复用:对于频繁访问的域名,可以实现连接池

2. 缓存机制:缓存静态资源,减少重复请求

3. 异步处理:使用async/await确保高并发性能

4. 内存管理:定期清理请求日志,避免内存泄漏

🛡️ 安全性考虑

1. 访问控制:添加IP白名单/黑名单机制

2. SSL证书验证:确保HTTPS请求的安全性

3. 请求过滤:过滤恶意请求和攻击尝试

4. 日志保护:敏感信息脱敏处理

📈 扩展性设计

1. 配置文件化:将设置项移到配置文件中

2. 插件架构:支持自定义请求处理插件

3. 集群部署:支持多实例负载均衡

4. 监控告警:集成监控系统,异常情况及时告警

🎯 总结

通过本文的学习,你已经掌握了:

🔑 三个核心要点

1. HTTP代理原理:理解了HTTP/HTTPS代理的工作机制和实现方式

2. C# 网络编程:学会了使用Socket和HttpClient进行网络通讯开发

3. 实战应用技巧:获得了可直接用于生产环境的代码模板和最佳实践

这套代理服务器不仅能解决日常开发中的网络访问问题,还能作为企业级应用的基础组件。记住,好的代码不仅要能运行,更要考虑性能、安全和可维护性

觉得有用的话,记得转发给更多需要的同行!你在使用过程中遇到了什么问题?或者有什么更好的优化建议?欢迎在评论区分享你的经验!

💬 互动话题

1. 你的项目中是否需要HTTP代理功能?主要用于解决什么问题?

2. 对于企业级应用,你认为还需要添加哪些功能特性?

相关信息

通过网盘分享的文件:AppBasicHttpProxyServer.zip 链接: https://pan.baidu.com/s/1V6WP2Akcs_JGq2MWtdO1Yg?pwd=nm9x 提取码: nm9x --来自百度网盘超级会员v9的分享

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!