【问题标题】:Sending image with HttpListener only working for some images使用 HttpListener 发送图像仅适用于某些图像
【发布时间】:2011-01-11 16:08:08
【问题描述】:

我正在尝试创建一个小型 http 代理服务。这不是很好。它能够提供 HTML 还可以,但它会阻塞图像。也就是一些图片。

通过我的代理发送一个 url 在响应中产生 19.4 kb(根据 firebug) 再次根据 firebug 的说法,直接访问该 url 也会在响应中产生 19.4 kb。不同的是,当我通过代理放置它时它不会显示,但当我直接浏览时它会显示。

完全不同的网址也可以正常工作。有人知道吗?

private void DoProxy()
{
    var http = listener.GetContext();
    string url = http.Request.QueryString["url"];
    WebRequest request = HttpWebRequest.Create(url);
    WebResponse response = request.GetResponse();
    http.Response.ContentType = response.ContentType;

    byte[] content;
    using (Stream responseStream = response.GetResponseStream())
        content = ReadAll(responseStream);
    http.Response.ContentLength64 = content.Length;
    http.Response.OutputStream.Write(content, 0, content.Length);
    http.Response.Close();
}

private byte[] ReadAll(Stream stream)
{
    IList<byte> array = new List<byte>();
    int b;
    while ((b = stream.ReadByte()) != -1)
        array.Add(Convert.ToByte(b));
    return array.ToArray();
}

【问题讨论】:

  • 附带说明 - 您不应该一次读取 ReadAll 中的原始流一个字节,这是非常无效的
  • 在您关闭响应之前,我会尝试刷新/关闭 OutputStream
  • @BrokenGlass 嗯,我还能怎么做?不保证在标头中提供 Content-Length。 Read 方法需要一个数组和一个读取计数 - 如果请求响应大于我选择的缓冲区大小,那么调整/更改数组的大小很麻烦?
  • 在下方添加了回复以解决此问题

标签: c# httplistener


【解决方案1】:

在您关闭响应之前,我会尝试刷新/关闭 OutputStream

另外,作为第二个建议,查看来自原始站点的 HTTP 流量,然后使用像 Fiddler 这样的 HTTP 调试器通过您的代理站点 - 使用您的代理时肯定会有所不同。

另外为了使 ReadAll 方法更有效,通常我会避免将全部内容加载到内存中,因为这会炸毁大文件 - 只需将它们直接从输入流流式传输到输出流。如果您仍想使用字节数组,请考虑以下(未经测试但应该可以):

private byte[] ReadAll(Stream stream)
{
    byte[] buffer = new byte[8192];
    int bytesRead = 1;
    List<byte> arrayList = new List<byte>();

    while (bytesRead > 0)
    {
        bytesRead = stream.Read(buffer, 0, buffer.Length);
        arrayList.AddRange(new ArraySegment<byte>(buffer, 0, bytesRead).Array);
    }
    return arrayList.ToArray();
}

【讨论】:

  • 感谢您的回答!实际试验了一下,做了一些和你的阅读方法类似的事情,发现是这样的,但不是第一次!一定是遗漏了一些字节或其他东西,很奇怪。总之感谢!根据您的建议,我只使用了 responseStream.CopyTo(Http.Response.OutputStream)。非常简单,而且有效。 :)
【解决方案2】:

你可以尝试替换

http.Response.Close();

http.Response.Flush();
http.Response.End();

【讨论】:

    【解决方案3】:

    问题可能是您没有指定响应的 MIME 类型。这些天的浏览器非常宽容,但也许有一种情况,浏览器不知道如何处理你卡在它喉咙里的任何东西。

    我编写了最小的基于文件的 http 服务器,presented here,据我所知,它可以毫无问题地提供图像。

    【讨论】:

      【解决方案4】:

      只需将文本响应和图像响应分开,分别编写输出。我确实喜欢下面,它对我有用。

      static void Main(string[] args)
          {
              HttpListener server = new HttpListener();
              server.Prefixes.Add("http://localhost:9020/");
              server.Start();
              Console.WriteLine("Listening...");
              while (true)
              {
                  try
                  { 
                  HttpListenerContext context = server.GetContext();
                  HttpListenerResponse response = context.Response;
                  String localpath = context.Request.Url.LocalPath;
                  string page = Directory.GetCurrentDirectory() + localpath;
                  string msg = "";
                  bool imgtest = false;
                  if (localpath == "/")
                    page = "index.html";
                  Console.WriteLine(localpath);
                  if (!page.Contains("jpg") && !page.Contains("png"))//Separates image request
                  { 
                     TextReader tr = new StreamReader(page);
                     msg = tr.ReadToEnd();
                     tr.Dispose();
                  }
                  else
                  {
                     byte[] output = File.ReadAllBytes(page);
                     response.ContentLength64 = output.Length;
                     Stream st1 = response.OutputStream;
                     st1.Write(output, 0, output.Length);
                     imgtest = true;
                  }
                  if (imgtest==false)
                  { 
                     byte[] buffer = Encoding.UTF8.GetBytes(msg);
                     response.ContentLength64 = buffer.Length;
                     Stream st = response.OutputStream;
                     st.Write(buffer, 0, buffer.Length);
                     context.Response.Close();
                  }
                  }
                  catch (Exception ex)
                  {
                      Console.WriteLine("Error:  "+ex);
                      Console.ReadKey();
                  }
              }
      

      【讨论】:

        猜你喜欢
        • 2015-01-13
        • 2021-05-13
        • 1970-01-01
        • 1970-01-01
        • 2012-07-28
        • 2022-01-26
        • 2020-09-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多