我有一个充当文件主机的类,本质上你用这个端口号启动这个类,并且它托管一个文件(在真实世界中,实际上是包含很多部分的较大文件的主机部分 - 但是我已经考虑到这一点,试图找到一些问题的底部)。当我托管一个小文件时,没有问题,并且所有功能都按预期工作,当我托管较大的文件时,我收到了一些不寻常的行为 - 特别是当我使用Windows Media Player向侦听器打开网址时。看起来,Windows媒体播放器发送获取请求以获取所有内容,然后发出第二个请求开始收集块 - 但这些总是导致“指定的网络无法找到”的例外。幸运的是,原始连接保持打开状态,并且文件在媒体播放器中运行 - 但是如果我然后尝试将滑块移动到文件中的特定点,它会触发另一个错误输出的请求 - 我设法让它显示窗口媒体根本不会让你移动滑块 - 但这对我们的目的不起作用。我已经尝试了在IIS中托管的相同文件,并且它看起来很好,并且嗅探了数据包和匹配(至少在httplistener死亡之前)...我错过了什么。HTTPListener类似乎在新建的时候切断旧连接,这是否正确?
这里是我使用的代码:
using SWAT.Apps.WebinarRecordingsViewer.Interfaces;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace SWAT.Apps.WebinarRecordingsViewer.Implementation.Common
{
public class FileHost : IFileHost
{
private long Port { get; set; }
private string MimeType { get; set; }
private PointerRecord PointerRecord { get; set; }
public string FileName { get; set; }
public string ResultingFilename { get; set; }
public virtual string Url
{
get
{
return "http://localhost:" + this.Port + "/";
}
}
public Guid Guid { get; set; }
public FileHost(string filename, PointerRecord pointerRecord, string mimeType, long port, string resultingFilename, string realurl)
{
this.Port = port;
this.MimeType = mimeType;
this.FileName = filename;
this.PointerRecord = pointerRecord;
this.ResultingFilename = resultingFilename;
this.RealUrl = realurl;
this.Guid = Guid.NewGuid();
}
public void Dispose()
{
this.Stop();
}
private bool Stopped { get; set; }
private bool Stopping { get; set; }
public void Stop()
{
if (!Stopped)
{
Stopping = true;
if (this.listener!=null)
{
this.listener.Abort();
}
}
this.listener.Close();
}
public HttpListener listener { get; set; }
public void Start()
{
Stopped = false;
Stopping = false;
this.listener = new HttpListener();
this.listener.Prefixes.Add(string.Format("http://localhost:{0}/", this.Port));
this.listener.Start();
IAsyncResult result = listener.BeginGetContext(new AsyncCallback(ListenerCallback), this.listener);
}
public void ListenerCallback(IAsyncResult result)
{
if (this.listener == null)
return;
HttpListenerContext context = this.listener.EndGetContext(result);
// Call EndGetContext to complete the asynchronous operation.
if (!Stopping)
{
this.listener.BeginGetContext(new AsyncCallback(ListenerCallback), this.listener);
this.WriteFile(context.Response, context.Request);
}
if (Stopping)
{
Stopped = true;
Stopping = false;
}
}
public string RealUrl { get; set; }
private void WriteFile(HttpListenerResponse response, HttpListenerRequest request)
{
using (FileStream fs = File.Open(/*this.FileName*/"f:\\work\\download.wmv",FileMode.Open, FileAccess.Read, FileShare.Read))
{
response.KeepAlive = true;
response.SendChunked = true;
bool doingRange = false;
// response.AddHeader("Last-Modified", "Sun, 14 Nov 2010 21:15:21 GMT");
// response.ProtocolVersion = new Version("1.1");
// response.AddHeader("Cache-Control", "max-age=86400");
// response.AddHeader("ETag", string.Format("\"{0}\"", this.Guid.ToString()));
response.AddHeader("Accept-Ranges", "bytes");
response.ContentType = this.MimeType;
long start = 0;
long length = fs.Length;//this.PointerRecord.Length;
Int64 endByte = length-1;
if (request.Headers["range"] != null)
{
doingRange = true;
start = long.Parse(request.Headers["range"].Split('=')[1].Split('-')[0].Trim()) ;
if ((request.Headers["range"].Split('=')[1].Split('-').Length > 1))
{
Int64 endread = 0;
Int64.TryParse(request.Headers["range"].Split('=')[1].Split('-')[1].Trim(), out endread);
if (endread > 0)
{
endByte = endread;
}
}
if ((endByte + 1) > this.PointerRecord.Length)
{
endByte = this.PointerRecord.Length - 1;
}
length = (endByte - start) + 1;
response.AddHeader("Content-Range", "bytes=" + start.ToString() + "-" + endByte.ToString() + "/" + fs.Length.ToString());
response.ContentLength64 = length;
}
else
{
response.ContentLength64 = fs.Length;
}
byte[] buffer = new byte[1024 * 1024 ];
fs.Seek(start, SeekOrigin.Begin);
long read =0;
long runningTotal = 0;
try
{
var stream = response.OutputStream;
while ((length > 0) && ((read = fs.Read(buffer, 0, buffer.Length)) > 0))
{
runningTotal += read;
// if the read overshoots the requested read length
if (runningTotal > length)
{
read = read - (runningTotal - length);
}
stream.Write(buffer, 0, Convert.ToInt32(read));
stream.Flush();
if (runningTotal >= length)
{
break;
}
}
stream.Close();
response.StatusCode = doingRange ? (int)HttpStatusCode.PartialContent : (int)HttpStatusCode.OK;
response.StatusDescription = (doingRange ? HttpStatusCode.PartialContent : HttpStatusCode.OK).ToString();
}
catch (Exception ex)
{
var test = ex.Message;
}
finally
{
fs.Close();
fs.Dispose();
}
}
}
public event EventHandler<FileHostEventArgs> Error;
public void OnError(FileDownloadEventArgs e)
{
throw new NotImplementedException();
}
}
}
我不相信这是媒体播放器的行为不端,还是它的东西在服务器代码...任何帮助/建议将是巨大的..