c# - 双向 http 流式传输

标签 c# apache http asp.net-web-api

以下场景对 HTTP 有效吗?

  1. 客户端向服务器发送 HTTP 头
  2. 服务器接收头并发送HTTP响应头
  3. 客户端流式传输 HTTP 正文(分块传输)
  4. 服务器接收请求主体 block 并发送 HTTP 响应主体 block (再次分块传输)

我尝试使用 HttpWebRequest 来实现它和 Asp.Net Web Api但是在客户端出现了这个错误

An unhandled exception of type 'System.NotSupportedException' occurred in System.dll

Additional information: The stream does not support concurrent IO read or write operations

客户端

static void Main(string[] args)
{
      HttpWebRequest request = WebRequest.Create("http://localhost.fiddler:16462/") as HttpWebRequest;
      request.SendChunked = true;
      request.ContentType = "application/octet-stream";
      request.Method = "POST";
      request.AllowWriteStreamBuffering = false;
      request.AllowReadStreamBuffering = false;
      request.Timeout = 3600000;

      var requestStream = request.GetRequestStream();
      var responseStream = request.GetResponse().GetResponseStream();
      int bufLength = 10 * 1024;

      byte[] requestBuffer = new byte[bufLength];
      byte[] responseBuffer = new byte[bufLength];

      for (int i = 0; i < 1024; ++i)
      {
          requestStream.Write(requestBuffer, 0, bufLength);
          responseStream.Read(responseBuffer, 0, bufLength);
      }

      requestStream.Close();
      responseStream.Close();
}

我验证了 TcpClient确实支持同步请求响应流。但是,很高兴看到 HttpWebRequest 也支持这一点。

using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace TcpClientTest
{
    class Program
    {
        static void Main(string[] args)
        {
            TcpClient client = new TcpClient("localhost", 16462);
            var stream = client.GetStream();

            byte[] buffer = Encoding.UTF8.GetBytes("POST http://localhost:16462/ HTTP/1.1\r\n");
            stream.Write(buffer, 0, buffer.Length);

            buffer = Encoding.UTF8.GetBytes("Content-Type: application/octet-stream\r\n");
            stream.Write(buffer, 0, buffer.Length);

            buffer = Encoding.UTF8.GetBytes("Host: localhost:16462\r\n");
            stream.Write(buffer, 0, buffer.Length);

            buffer = Encoding.UTF8.GetBytes("Transfer-Encoding: chunked\r\n\r\n");
            stream.Write(buffer, 0, buffer.Length);

            int chunkLen = 128 * 1024;
            string chunkSizeStr = chunkLen.ToString("X");
            byte[] chunkSizeBytes = Encoding.UTF8.GetBytes(chunkSizeStr + "\r\n");
            buffer = new byte[chunkLen];
            for (int i = 0; i < chunkLen; ++i)
            {
                buffer[i] = (byte)'a';
            }

            // Start reader thread
            var reader = new Thread(() =>
            {
                byte[] response = new byte[128 * 1024];
                int bytesRead = 0;
                while ((bytesRead = stream.Read(response, 0, response.Length)) > 0)
                {
                    Console.WriteLine("Read {0} bytes", bytesRead);
                }
            });

            reader.Start();

            // Streaming chunks
            for (int i = 0; i < 1024 * 1024; ++i)
            {
                stream.Write(chunkSizeBytes, 0, chunkSizeBytes.Length);
                stream.Write(buffer, 0, buffer.Length);
                stream.Write(Encoding.UTF8.GetBytes("\r\n"), 0, 2);
            }

            buffer = Encoding.UTF8.GetBytes("0\r\n\r\n");
            stream.Write(buffer, 0, buffer.Length);
            reader.Join();
        }
    }
}

最佳答案

这似乎不是有效的 HTTP 行为。您可以创建一个自定义的“类似 HTTP”的客户端和服务器,在客户端完成请求之前开始发送响应,但根据 the HTTP spec 这似乎无效:

6 Response

  After receiving and interpreting a request message, a server responds
  with an HTTP response message.

Web 套接字可能是您的菜!它们允许在 HTTP 之上的双向流。 https://en.wikipedia.org/wiki/WebSocket

关于c# - 双向 http 流式传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28305709/

相关文章:

apache - 重定向到另一个域而不影响 SEO

c# - 快速轻松地从一个文件加载所需内容?

c# - WCF 每个连接服务器证书验证

c# - 将文件写入 HttpResponse,浏览器不提示保存

java - Android KitKat chrome ://inspect/devices network monitoring, 如何查看所有请求数据

c# - HttpRequestHeader cookie 格式

python - 使用 Stackless Python 3.1 的基本异步(非阻塞)HTTP 客户端有现成的解决方案吗?

c# - String.Format - 从 C++ 迁移到 C#

linux - 如何在 Ubuntu 服务器上设置权限以允许 Apache 用户和第二个用户写入 Web 目录?

java - Apache POI autoSizeColumn() 无法正常工作