C#实现http协议GET、POST请求教程
云计算
C#实现http协议GET、POST请求教程
2025-03-13 00:22
使用 DnsEndPoint自动解析DNS记录 设置5秒超时防止僵死连接 2. SSL/TLS加密通道
?️ 基础代码增强版
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Text;
class HttpSocketClient : IDisposable
{
private const int BufferSize = 4096;
private readonly Socket _socket;
private readonly NetworkStream _stream;
private readonly SslStream _sslStream;
private bool _disposed;
public HttpSocketClient(string host, int port, bool useSsl)
{
// 创建TCP套接字
_socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp)
{
SendTimeout = 5000,
ReceiveTimeout = 5000
};
// 建立连接
var endpoint = new DnsEndPoint(host, port);
_socket.Connect(endpoint);
// 创建网络流
_stream = new NetworkStream(_socket, FileAccess.ReadWrite, true);
// SSL/TLS处理
if (useSsl)
{
_sslStream = new SslStream(_stream, false, ValidateServerCertificate);
_sslStream.AuthenticateAsClient(host);
}
}
public string SendRequest(string method, string path, Dictionary<string, string> headers)
{
// 构造请求报文
var request = BuildRequest(method, path, headers);
byte[] requestBytes = Encoding.ASCII.GetBytes(request);
// 发送请求
( _sslStream ?? (Stream)_stream ).Write(requestBytes);
// 接收响应
return ReadResponse();
}
private string BuildRequest(string method, string path, Dictionary<string, string> headers)
{
var sb = new StringBuilder();
sb.Append($"{method} {path} HTTP/1.1\r\n");
foreach (var header in headers)
{
sb.Append($"{header.Key}: {header.Value}\r\n");
}
sb.Append("\r\n");
return sb.ToString();
}
private string ReadResponse()
{
// 解析响应头和正文
using var memStream = new MemoryStream();
var buffer = new byte[BufferSize];
int bytesRead;
do
{
bytesRead = ( _sslStream ?? (Stream)_stream ).Read(buffer, 0, BufferSize);
memStream.Write(buffer, 0, bytesRead);
} while (bytesRead > 0);
return Encoding.UTF8.GetString(memStream.ToArray());
}
private bool ValidateServerCertificate(object sender, X509Certificate certificate,
X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
// 实际生产环境需验证证书合法性
return true; // 测试环境跳过验证
}
public void Dispose()
{
if (_disposed) return;
_sslStream?.Dispose();
_stream?.Dispose();
_socket?.Dispose();
_disposed = true;
}
}
? 核心代码解析
1. 连接初始化
var endpoint = new DnsEndPoint(host, port);
_socket.Connect(endpoint);
- 使用
DnsEndPoint
自动解析DNS记录 - 设置5秒超时防止僵死连接
2. SSL/TLS加密通道
_sslStream.AuthenticateAsClient(host);
- 支持HTTPS协议加密传输
ValidateServerCertificate
需实现证书校验逻辑
3. 请求构造器
sb.Append($"{method} {path} HTTP/1.1\r\n");
- 严格遵循HTTP报文格式
- 自动生成标准请求头
4. 响应接收优化
do {
bytesRead = stream.Read(buffer, 0, BufferSize);
memStream.Write(buffer, 0, bytesRead);
} while (bytesRead > 0);
- 使用内存流提高读取效率
- 4KB缓冲区平衡内存与性能
⚡️ 使用示例
using var client = new HttpSocketClient("example.com", 443, true);
var headers = new Dictionary<string, string>
{
["Host"] = "example.com",
["User-Agent"] = "CustomSocketClient/1.0",
["Accept"] = "text/html"
};
try
{
string response = client.SendRequest("GET", "/api/data", headers);
Console.WriteLine(response);
}
catch (SocketException ex)
{
Console.WriteLine($"网络错误: {ex.SocketErrorCode}");
}
?️ 安全增强方案
1. 证书验证(生产环境必备)
private bool ValidateServerCertificate(...)
{
if (sslPolicyErrors != SslPolicyErrors.None)
return false;
var cert = new X509Certificate2(certificate);
return cert.Verify();
}
2. 请求头注入防护
foreach (var header in headers)
{
if (header.Key.Contains('\r') || header.Value.Contains('\n'))
throw new ArgumentException("非法头信息");
}
3. 响应大小限制
const int MaxResponseSize = 10 * 1024 * 1024; // 10MB
if (memStream.Length > MaxResponseSize)
throw new InvalidOperationException("响应超限");
? 与HttpClient对比
特性 | Socket实现 | HttpClient |
---|---|---|
协议控制粒度 | ⭐⭐⭐⭐⭐ | ⭐⭐ |
连接复用能力 | ⭐⭐ | ⭐⭐⭐⭐⭐ |
开发复杂度 | ⭐ | ⭐⭐⭐⭐⭐ |
性能优化空间 | ⭐⭐⭐⭐ | ⭐⭐⭐ |
标准协议支持 | 需手动实现 | 自动处理 |
? 应用场景建议
适合使用Socket的情况:
✅ 需要实现自定义传输协议
✅ 进行网络层性能调优
✅ 处理特殊网络设备通信
推荐使用HttpClient的情况:
✅ 快速实现标准HTTP通信
✅ 需要连接池管理
✅ 依赖注入场景
通过本方案可深入理解HTTP协议底层机制,但实际生产环境建议优先使用 HttpClient
。如需深度优化网络性能,可参考《.NET高性能网络编程》专业文献。开发完成后务必进行:
? 压力测试
? 安全审计
? 性能剖析
标签:
- C#
- GET
- http
- POST