【问题标题】:C#, clear HttpListenerContext.Response.OutputStreamC#,清除 HttpListenerContext.Response.OutputStream
【发布时间】:2018-07-13 23:24:05
【问题描述】:

我有一个使用 HttpListener 的网络服务。

我注意到了这件事:

HttpListenerContext context = listener.GetContext();
...
context.Response.StatusCode = 200;
context.Response.OutputStream.Write(buffer, 0, bufferSize);
context.Response.StatusCode = 500;
context.Response.OutputStream.Close();

在这种情况下,客户端收到状态代码 200,因此如果我已将一些数据写入输出网络流,我无法更改状态代码,因为我想它已经写入响应流。

我想要什么:在我开始向输出流写入响应后,在某些情况下我想“中止并重置”响应,清除输出流(这样客户端就不会在 HTTP 响应中收到任何数据body),并更改状态码。

我不知道如何清除输出流和更改状态码。下面这两行无济于事,它们会引发异常。

context.Response.OutputStream.SetLength(0);
context.Response.OutputStream.Position = 0;

我想,在我调用 context.Response.OutputStream.Close() 之后程序将缓冲区数据写入网络设备,直到数据存储在 RAM 中,我们可以重置它,不是吗?

编辑: 在某些情况下,有时写入 context.Response.OutputStream 似乎需要太多时间。从 100 到 1000 毫秒……这就是为什么我会打断写作,如果可能的话。

【问题讨论】:

  • 你可以将所有数据写入一个临时的 MemoryStream,但是一旦写入 Response 流,就无法取回
  • 是的,但在某些情况下,有时写入 context.Response.OutputStream 似乎需要太多时间。从 100 到 1000 毫秒……这就是为什么我会中断写作,如果可能的话。但你回答了这是不可能的。
  • StatusCode 是标头的一部分,因此当您开始编写输出时,标头会先出现,以后不会再出现。该流是只写的,因此没有像位置控制这样的东西,它会在您写入时连续发送。

标签: c# http server


【解决方案1】:

您可以使用 MemoryStream 来缓存答案,如果您确定它是完整的,请将状态设置为 200 并返回它(例如使用 Stream.CopyTo)。

您无法“清除”OutputStream,因为它不会(长时间)存储,而是立即发送到客户端,因此您无法再对其进行编辑。

除此之外,HTTP 不提供优雅地说“DATADATADATA...哦忘记了,这是错误的,请改用状态码 500。”的方式。您只能尝试终止 TCP 连接(TCP RST 而不是 TCP FIN),并希望客户端在可能已经开始处理您已经发送的数据之后,能够以合适的方式处理无法继续读取连接的问题.

在关闭之前尝试 context.Response.Abort(),这将不允许您设置状态代码,但至少会传达出问题所在。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-18
    • 2016-06-14
    • 2011-10-02
    • 1970-01-01
    • 2011-01-03
    • 2011-03-02
    • 2010-10-12
    • 1970-01-01
    相关资源
    最近更新 更多