C# 使用TCP创建HTTP客户程序
首先,創建一個控制臺應用程序(包),向 Web 服務器發送一個 HTTP 請求。以前用 HttpClient 類實現了這個功能,但使用 TcpClient 類需要深入 HTTP 協議。
HttpClientUsingTcp 示例代碼使用了以下名稱空間:
System System.IO System.Net.Sockets System.Text System.Threading.Tasks應用程序接受一個命令行參數,傳遞服務器的名稱。這樣,就調用RequestHtmlAsync 方法,向服務器發出 HTTP 請求。它用 Task 的 Result 屬性返回一個字符串:
static void Main(string[] args) {if (args.Length != 1){ShowUsage();}Task<string> tl = RequestHtmlAsync(args[0]); Console.WriteLine(t1.Result); Console.ReadLine(); }private static void ShowUsage() {Console.WriteLine("Usage: HttpClientUsingTcp hostname"); }現在看看 RequestHtmlAsync 方法的最重要部分。首先,實例化一個 TcpClient 對象。其次,使用 ConnectAsync 方法,在 HTTP 默認端口 80 上建立到主機的TCP 連接。再次,通過 GetStream 方法檢索一個流,使用這個連接進行讀寫:
private const int ReadBufferSize = 1024; public static async Task<string> RequestHtmlAsync(string hostname) {try{using (var client = new TcpClient()){await?client.ConnectAsync(hostname, 80);?NetworkStream?stream?=?client.GetStream();//...}} }流現在可以用來把請求寫到服務器,讀取響應。HTTP 是一種基于文本的協議,所以很容易在字符串中定義請求。為了向服務器發出一個簡單的請求,標題定義了 HTTP 方法 GET,其后是 URL/ 的路徑和 HTTP 版本 HTTP/1.1。第二行定義了 Host 標題、主機名和端口號,第三行定義了 Connection 標題。通常,通過Connection 標題,客戶端請求 keep-alive,要求服務器保持連接打開,因為客戶端希望發出更多的請求。這里只向服務器發出一個請求,所以服務器應該關閉連接,從而 close 設置為 Connection 標題。為了結束標題信息,需要使用 \r\n 給請求添加一個空行。標題信息調用 NetworkStream 的方法 WriteAsync,用UTF-8 編碼發送。\r\n 為了立即向服務器發送緩存,請調用 FlushAsync 方法。否則數據就可能保存在本地緩存:
//... string header = "GET/HTTP/1.1\r\n" + $"Host: {hostname}:80\r\n" + "Connection: close\r\n" + "\r\n"; byte[] buffer = Encoding.UTF8.GetBytes(header); await stream.WriteAsync(buffer, 0, buffer.Length); await?stream.FlushAsync();現在可以繼續這個過程,從服務器中讀取回應。不知道回應有多大,所以創建一個動態生長的 MemoryStream。使用 ReadAsync 方法把服務器的回應暫時寫入一個字節數組,這個字節數組的內容添加到 MemoryStream 中。從服務器中讀取所有數據后,StreamReader 接管控制,把數據從流讀入一個字符串,并返回給調用者:
var ms = new MemoryStream(); buffer?=?new?byte[ReadBufferSize];? int?read?=?0;? do {read?= await?stream.ReadAsync(buffer, 0, ReadBufferSize);?ms.Write(buffer,?0,?read);Array.Clear(buffer, 0, buffer.Length);} while (read > 0);ms.Seek(0, SeekOrigin.Begin);var?reader?= new?StreamReader(ms);?return?reader.ReadToEnd(); } //...1
把一個網站傳遞給程序,會看到一個成功的請求,其 HTML 內容顯示在控制臺上。現在該創建一個 TCP 偵聽器和自定義協議了。
?微信公眾號?
Dotnet
總結
以上是生活随笔為你收集整理的C# 使用TCP创建HTTP客户程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 发布nuget包的正确姿势---cicd
- 下一篇: Azure DevOps 中 Dapr项