使用HttpListener处理范围请求当尝试加载视频时(看似一定大小,因为它不会每次都发生),浏览器请求带有此标头的视频文件:方法:GET/media/mp4/32.mp4Connection-keep-aliveAccept-*/*Accept-Encoding-identity;q=1/*;q=0Accept-Language-en-us/en;q=0.8Host-localhost:20809Referer-...Range-bytes=0-User-Agent-Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/33.0.1750.170Safari/537.36所以服务器发送请求的文件...然后,紧接着,请求:方法:GET/media/mp4/32.mp4Connection-keep-aliveAccept-*/*Accept-Encoding-identity;q=1/*;q=0Accept-Language-en-us/en;q=0.8Host-localhost:20809Referer-...Range-bytes=40-3689973User-Agent-Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/33.0.1750.170Safari/537.36所以我将请求的字节写入输出流,但它总是出错并在第二次请求时出错。这几乎就好像在浏览器发送另一个请求时服务器仍在尝试发送文件一样。由于线路退出或应用程序请求,I/O操作已停止以下是处理范围请求的代码:publicvoidStartServer(){_server=newHttpListener();_server.Prefixes.Add("http://localhost:"+_port.ToString()+"/");LogWebserver("正在收听...");_server.Start();th=newThread(newThreadStart(startlistener));th.Start();}privatevoidstartlistener(){while(true){////阻塞直到客户端连接到服务器ProcessRequest();}}privatevoidProcessRequest(){varresult=_server.BeginGetContext(ListenerCallback,_server);结果.AsyncWaitHandle.WaitOne();}privatevoidListenerCallback(IAsyncResultresult){varcontext=_server.EndGetContext(result);句柄上下文(上下文);}privatevoidHandleContext(HttpListenerContextcontext){HttpListenerRequestreq=context.Request;...东西...使用(HttpListenerResponseresp=context.Response){....东西....byte[]buffer=File.ReadAllBytes(localFile);如果(mime.ToString().Contains("视频")||mime.ToString().Contains("音频")){resp.StatusCode=206;resp.StatusDescription="部分内容";intstartByte=-1;intendByte=-1;intbyteRange=-1;if(req.Headers.GetValues("Range")!=null){stringrangeHeader=req.Headers.GetValues("Range")[0].Replace("bytes=","");string[]range=rangeHeader.Split('-');startByte=int。解析(范围[0]);如果(范围[1]。修剪()。长度>0)int.TryParse(范围[1],输出endByte);如果(endByte==-1)endByte=buffer.Length;}else{startByte=0;endByte=buffer.Length;}byteRange=endByte-startByte;resp.ContentLength64=byteRange;resp.Headers.Add("Accept-Ranges","bytes");resp.Headers.Add("Content-Range",string.Format("bytes{0}-{1}/{2}",startByte,byteRange-1,byteRange));resp.Headers.Add("X-Content-Duration","0.0");resp.Headers.Add("Content-Duration","0.0");resp.OutputStream.Write(buffer,startByte,byteRange);/*这是它给出IO错误的地方*/resp.OutputStream.Close();resp.Close();}else{resp.CointentLength64=buffer.Length;resp.OutputStream.Write(buffer,0,buffer.Length);resp.OutputStream.Close();分别关闭();我试过忽略带有范围的请求,但没有抛出错误,浏览器抛出错误,因为视频未下载如何处理这些范围请求并避免IO错误?我解决了这个问题,但它涉及废弃HttpListener并改用TcpListener。我使用这里的代码作为服务器的基础:http://www.codeproject.com/Articles/137979/Simple-HTTP-Server-in-C然后我用这个修改了handleGETRequest函数:if(mime.ToString().Contains("video")||mime.ToString().Contains("audio")){使用(FileStreamfs=newFileStream(localFile,FileMode.Open)){intstartByte=-1;intendByte=-1;如果(p.httpHeaders.Contains("Range")){stringrangeHeader=p.httpHeaders["Range"].ToString().Replace("bytes=","");string[]range=rangeHeader.Split('-');startByte=int.Parse(范围[0]);如果(范围[1]。修剪()。长度>0)int.TryParse(范围[1],出endByte);如果(endByte==-1)endByte=(int)fs.Length;}else{开始字节=0;endByte=(int)fs.Length;}byte[]buffer=newbyte[endByte-startByte];fs.Position=startByte;intread=fs.Read(buffer,0,endByte-startByte);fs.Flush();fs.Close();p.outputStream.AutoFlush=true;p.outputStream.WriteLine("HTTP/1.0206部分内容");p.outputStream.WriteLine("内容类型:"+mime);p.outputStreamm.WriteLine("Accept-Ranges:bytes");inttotalCount=startByte+buffer.Length;p.outputStream.WriteLine(string.Format("Content-Range:bytes{0}-{1}/{2}",startByte,totalCount-1,totalCount));p.outputStream.WriteLine("内容长度:"+buffer.Length.ToString());p.outputStream.WriteLine("Connection:keep-alive");p.outputStream.WriteLine("");p.outputStream.AutoFlush=false;p.outputStream.BaseStream.Write(buffer,0,buffer.Length);p.outputStream.BaseStream.Flush();}}else{byte[]buffer=File.ReadAllBytes(localFile);p.outputStream.AutoFlush=true;p.outputStream.WriteLine("HTTP/1.0200OK");p.outputStream.WriteLine("内容类型:"+mime);p.outputStream.WriteLine("连接:关闭");p.outputStream.WriteLine("内容长度:"+buffer.Length.ToString());p.outputStream.WriteLine("");p.outputStream.AutoFlush=false;p.outputStream.BaseStream.Write(buffer,0,buffer.Length);p.outputStream.BaseStream.Flush();}使用TcpListener您可以避免在响应流上导致I/O错误的任何愚蠢问题。以上就是C#学习教程:使用HttpListener处理范围请求的全部内容。注意——本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
