C# 使用HttpListener发送图像仅适用于某些图像
我正在尝试创建一个小型http代理服务。这不太好用。它能够提供HTML okayish,但是它会被图像阻塞。也就是说,一些图像 通过我的代理发送url会在响应中产生19.4KB(根据firebug) 根据firebug的说法,直接访问该url也会产生19.4KB的响应。不同的是,当我把它放到我的代理中时,它不会显示,但是当我直接浏览时它会显示 一个完全不同的url很好用。有人知道吗C# 使用HttpListener发送图像仅适用于某些图像,c#,httplistener,C#,Httplistener,我正在尝试创建一个小型http代理服务。这不太好用。它能够提供HTML okayish,但是它会被图像阻塞。也就是说,一些图像 通过我的代理发送url会在响应中产生19.4KB(根据firebug) 根据firebug的说法,直接访问该url也会产生19.4KB的响应。不同的是,当我把它放到我的代理中时,它不会显示,但是当我直接浏览时它会显示 一个完全不同的url很好用。有人知道吗 private void DoProxy() { var http = listener.GetConte
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();
}
private void DoProxy()
{
var http=listener.GetContext();
字符串url=http.Request.QueryString[“url”];
WebRequest=HttpWebRequest.Create(url);
WebResponse=request.GetResponse();
http.Response.ContentType=Response.ContentType;
字节[]内容;
使用(Stream responseStream=response.GetResponseStream())
内容=ReadAll(responseStream);
http.Response.ContentLength64=content.Length;
http.Response.OutputStream.Write(content,0,content.Length);
http.Response.Close();
}
专用字节[]ReadAll(流)
{
IList数组=新列表();
int b;
而((b=stream.ReadByte())!=-1)
Add(Convert.ToByte(b));
返回array.ToArray();
}
您可以尝试替换
http.Response.Close();
与
问题可能是您没有指定响应的MIME类型。浏览器这些日子是非常宽容的,但也许有一种情况,浏览器不知道如何处理你从它喉咙里伸出来的东西
我编写了最小型的基于文件的http服务器,据我记忆所及,它可以毫无问题地提供图像。在关闭响应之前,我会尝试刷新/关闭
输出流
另外,作为第二个建议,请查看来自原始站点的HTTP流量,然后使用HTTP调试器通过代理站点,如-使用代理时一定会有所不同
另外,为了使ReadAll方法更有效,通常我会避免将全部内容加载到内存中,因为这会导致巨大的文件爆炸——只需将它们直接从输入流流传输到输出流。如果仍想使用字节数组,请考虑以下(未经测试但应工作):
private byte[]ReadAll(流)
{
字节[]缓冲区=新字节[8192];
int字节读取=1;
List arrayList=新列表();
而(字节读取>0)
{
bytesRead=stream.Read(buffer,0,buffer.Length);
AddRange(新的ArraySegment(缓冲区,0,字节读取).Array);
}
返回arrayList.ToArray();
}
只需将文本响应和图像响应分开,并分别写入输出。我确实喜欢下面的内容,它对我很有用
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();
}
}
作为旁注-您不应该一次读取一个字节的ReadAll来读取原始流,这是非常无效的。在关闭前,我会尝试刷新/关闭OutputStream
response@BrokenGlass嗯,要不然我怎么做呢?标题中不保证提供内容长度。读取方法需要一个数组和一个读取计数-如果请求-响应大于我选择的缓冲区大小,则调整/更改数组会很麻烦?下面添加了一个响应来解决此问题谢谢您的回答!实际上做了一些实验,做了一些类似于你的阅读方法的事情,发现它是这样工作的,但不是第一次!一定是漏了字节什么的,奇怪的。无论如何,谢谢!根据您的建议,我只使用了responseStream.CopyTo(Http.Response.OutputStream)。非常简单,而且有效。:)
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();
}
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();
}
}