Web Proxy(Web 代理伺服器)是網路應用中經典的「中介者」模式實作。本文將系統性說明:代理伺服器的優勢與風險、分層代理類型(應用層/傳輸層/SOCKS)、HTTP 代理的運作流程,並完整實作一個基於 TcpListener + Socket + 多執行緒的 C# HTTP Proxy,支援瀏覽器設定代理後直接瀏覽網頁。
| 優勢 | 說明 |
|---|---|
| IP 位址共享 | 區域網路內多台主機共用極少對外公網 IP |
| 存取控制 | 可過濾特定 IP/網域,充當防火牆角色 |
| 匿名性 | 目標伺服器只看見 Proxy IP,隱藏客戶端真實身分 |
| 快取加速 | 熱門資源暫存於 Proxy 硬碟,重複請求直接回應 |
風險提醒:所有流量經由 Proxy,若 Proxy 被惡意竊聽或頻寬不足,將導致資安外洩或速度下降。
關鍵點:每個客戶端請求獨立處理,故採用「一請求一執行緒」模型,每執行緒持有兩個 Socket(clientSocket 與 serverSocket)。
public class Proxy
{
private Socket _clientSocket;
private byte[] _buffer = new byte[4096];
private Encoding _ascii = Encoding.ASCII;
public Proxy(Socket clientSocket) => _clientSocket = clientSocket;
public void Run()
{
// 1. 讀取客戶端請求
string request = ReadRequest();
if (string.IsNullOrEmpty(request)) return;
// 2. 解析目標 URL (簡易解析 GET https://host/path)
string url = ParseUrl(request);
if (string.IsNullOrEmpty(url)) return;
// 3. 連線目標伺服器
using var serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var hostEntry = Dns.GetHostEntry(url);
var ipEndPoint = new IPEndPoint(hostEntry.AddressList[0], 80);
serverSocket.Connect(ipEndPoint);
// 4. 轉發請求
byte[] reqBytes = _ascii.GetBytes(request);
serverSocket.Send(reqBytes);
// 5. 接收回應並轉發給客戶端
RelayResponse(serverSocket);
}
private string ReadRequest() { /* 讀取直到雙 CRLF 或 Content-Length */ }
private string ParseUrl(string request) { /* 簡易字串解析 */ }
private void RelayResponse(Socket server) { /* 迴圈 Receive/Send */ }
}
const int PORT = 8000;
var listener = new TcpListener(IPAddress.Any, PORT);
listener.Start();
Console.WriteLine($"Proxy listening on {PORT}...");
while (true)
{
Socket clientSocket = listener.AcceptSocket();
var proxy = new Proxy(clientSocket);
Thread thread = new Thread(proxy.Run) { IsBackground = true };
thread.Start();
}
範例使用簡易 IndexOf 切割第一行 GET https://host/path HTTP/1.1。實務上需完整解析:
CONNECT 方法(HTTPS 隧道)Host 標頭(HTTP/1.1 必備)Chunked Transfer-Encoding、Content-Length、Gzip 等Connection: keep-alive 連線重用範例使用同步 Send/Receive + 執行緒池,適合低併發。高併發建議改用:
SocketAsyncEventArgs 或 await Socket.ReceiveAsyncPipe / Stream 雙向複製(CopyToAsync)
// 客戶端發送:CONNECT www.example.com:443 HTTP/1.1
// Proxy 回應:HTTP/1.1 200 Connection Established
// 之後雙向透傳 TLS 封包,Proxy 不解密內容
完整 Proxy 必須實作 CONNECT,否則無法代理 HTTPS 流量。
IE/Edge/Chrome 系統代理設定:
現代瀏覽器也可用擴充套件(SwitchyOmega、Proxy Switchy)切換。
HttpClient + HttpRequestMessage 替代手工 Socket,自動處理協定細節。MapReverseProxy / YARP)。IMemoryCache/Redis)。這個範例雖然簡單,卻完整展示了 HTTP Proxy 的核心架構:監聽 → 分派執行緒 → 解析請求 → 建立上游連線 → 雙向轉發。理解這個流程,是深入網路程式設計、開發爬蟲中介、API Gateway、安全掃描器等進階應用的基石。現代開發建議站在巨人肩膀上(YARP、Titanium Web Proxy),專注於業務邏輯而非重造輪子。