You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 6中如何直接获取无HTTP协议的Socket流?

在.NET 6中获取HTTP升级后的原始Socket流

要实现自定义协议的HTTP升级并获取底层Socket流,你可以利用ASP.NET Core的IHttpUpgradeFeature特性,以下是具体实现步骤:

1. 配置中间件处理升级请求

在Program.cs中添加自定义中间件,拦截带有Upgrade和Connection: upgrade头部的请求:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// 自定义协议处理中间件
app.Use(async (context, next) =>
{
    // 检查是否是目标升级请求
    var upgradeFeature = context.Features.Get<IHttpUpgradeFeature>();
    if (upgradeFeature != null 
        && context.Request.Headers.TryGetValue("Connection", out var connectionHeader)
        && connectionHeader.ToString().IndexOf("upgrade", StringComparison.OrdinalIgnoreCase) >= 0
        && context.Request.Headers.TryGetValue("Upgrade", out var upgradeHeader)
        && upgradeHeader.ToString().Equals("myprotocol", StringComparison.OrdinalIgnoreCase))
    {
        // 发送101协议切换响应
        context.Response.StatusCode = StatusCodes.Status101SwitchingProtocols;
        context.Response.Headers.Append("Connection", "Upgrade");
        context.Response.Headers.Append("Upgrade", "myprotocol");

        // 获取升级后的原始Socket流
        using var stream = await upgradeFeature.UpgradeAsync();
        
        // 此处可直接读写stream,进行自定义协议通信
        // 示例:读取客户端数据并返回
        var buffer = new byte[1024];
        int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
        if (bytesRead > 0)
        {
            string receivedData = Encoding.UTF8.GetString(buffer, 0, bytesRead);
            var responseBytes = Encoding.UTF8.GetBytes($"Received: {receivedData}");
            await stream.WriteAsync(responseBytes, 0, responseBytes.Length);
            await stream.FlushAsync();
        }

        // 处理完成后直接返回,跳过后续中间件
        return;
    }

    // 非升级请求,交给后续中间件处理
    await next(context);
});

app.Run();

关键说明

  • IHttpUpgradeFeature是ASP.NET Core的核心特性,专门用于处理HTTP协议升级场景,调用UpgradeAsync()返回的Stream就是底层Socket流,不再包含HTTP协议头。
  • 必须先返回101 Switching Protocols状态码,并设置对应响应头部,完成协议切换的握手流程。
  • 自定义协议名称(示例中的myprotocol)需要客户端和服务端保持一致,确保升级逻辑能正确匹配。

客户端测试示例(C#)

你可以用以下代码测试服务端的自定义协议:

using var client = new TcpClient("localhost", 5000);
using var stream = client.GetStream();

// 发送HTTP升级请求
var request = "GET / HTTP/1.1\r\n" +
              "Host: localhost:5000\r\n" +
              "Connection: Upgrade\r\n" +
              "Upgrade: myprotocol\r\n\r\n";
var requestBytes = Encoding.UTF8.GetBytes(request);
await stream.WriteAsync(requestBytes, 0, requestBytes.Length);
await stream.FlushAsync();

// 读取101响应头
var responseBuffer = new byte[1024];
int responseBytesRead = await stream.ReadAsync(responseBuffer, 0, responseBuffer.Length);
string responseHeader = Encoding.UTF8.GetString(responseBuffer, 0, responseBytesRead);
Console.WriteLine("响应头:\n" + responseHeader);

// 发送自定义协议数据
var customData = "Hello Custom Protocol!";
var customDataBytes = Encoding.UTF8.GetBytes(customData);
await stream.WriteAsync(customDataBytes, 0, customDataBytes.Length);
await stream.FlushAsync();

// 读取服务端返回的自定义协议数据
var resultBuffer = new byte[1024];
int resultBytesRead = await stream.ReadAsync(resultBuffer, 0, resultBuffer.Length);
string result = Encoding.UTF8.GetString(resultBuffer, 0, resultBytesRead);
Console.WriteLine("服务端返回:" + result);

内容的提问来源于stack exchange,提问作者user1870379

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 22:02:19