首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# Socket 編程實戰:手工構造 HTTP GET 請求與響應解析

     編輯:關於C語言

核心代碼


public string DoSocketGet(string server)
{
    Encoding ascii = Encoding.ASCII;
    string request = $"GET / HTTP/1.1\r\nHost: {server}\r\nConnection: Close\r\n\r\n";
    byte[] sendBytes = ascii.GetBytes(request);
    byte[] recvBuffer = new byte[256];
    string response = null;

    // 解析 IP
    IPAddress ip = Dns.GetHostAddresses(server)[0];
    IPEndPoint endPoint = new IPEndPoint(ip, 80);

    // 創建 TCP Socket
    using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
    {
        socket.Connect(endPoint);
        if (!socket.Connected)
            return "Unable to connect to host";

        // 發送請求
        socket.Send(sendBytes, sendBytes.Length, SocketFlags.None);

        // 接收響應循環
        int bytes = socket.Receive(recvBuffer, recvBuffer.Length, SocketFlags.None);
        response = $"Default HTML page on {server}:\r\n";
        response += ascii.GetString(recvBuffer, 0, bytes);

        while (bytes > 0)
        {
            bytes = socket.Receive(recvBuffer, recvBuffer.Length, SocketFlags.None);
            response += ascii.GetString(recvBuffer, 0, bytes);
        }
    }
    return response;
}

關鍵步驟解析

步驟API說明
DNS 解析Dns.GetHostAddresses獲取域名對應 IP 列表,取第一個
端點構造IPEndPoint(ip, 80)HTTP 默認端口 80
Socket 創建new Socket(InterNetwork, Stream, Tcp)IPv4、流式、TCP 協議
連接Connect(endPoint)三次握手建立連接
發送Send(byte[], int, SocketFlags)發送原始 HTTP 請求字節
接收循環Receive(byte[], int, SocketFlags)阻塞讀取直到連接關閉 (Connection: Close)

HTTP 協議要點

  • 請求行:GET / HTTP/1.1
  • Host 頭:HTTP/1.1 必須,支持虛擬主機
  • Connection: Close:告知服務端響應後關閉連接,客戶端才能靠 Receive 返回 0 判斷結束
  • 雙 CRLF (\r\n\r\n) 結束請求頭

改進建議

  • 使用 HttpWebRequest/HttpClient 替代手工 Socket(生產環境)
  • 支持 HTTPS:需 SslStream 包裝 Socket 進行 TLS 握手
  • 異步模式:BeginSend/EndSend、BeginReceive/EndReceive 或 SendAsync/ReceiveAsync
  • 完整響應解析:分離狀態行、頭部、實體體,處理 Chunked、Content-Length、Gzip 等
  • 緩衝區動態擴展:List 或 MemoryStream 避免固定 256 字節截斷

錯誤處理


try
{
    // ... socket operations
}
catch (SocketException ex) when (ex.SocketErrorCode == SocketError.ConnectionRefused)
{
    return "Connection refused";
}
catch (SocketException ex)
{
    return $"Socket error: {ex.Message}";
}
catch (Exception ex)
{
    return $"General error: {ex.Message}";
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved