当客户端关闭连接时,HttpListenerResponse
类有问题我无法将响应复制到outputStream,因为流被中断,所以它是合乎逻辑的。有一些简单的方法可以解决它或处理这种异常。我知道HttpListener
不是代理服务器的最佳解决方案。
我尝试将属性IgnoreWriteExceptions
设置为true但不起作用。
public class Ask
{
private int requestCounter = 0;
private ManualResetEvent stopEvent = new ManualResetEvent(false);
public class HttpListenerCallbackState
{
private readonly HttpListener _listener;
private readonly System.Threading.AutoResetEvent _listenForNextRequest;
public HttpListenerCallbackState(HttpListener listener)
{
if (listener == null) throw new ArgumentNullException("listener");
_listener = listener;
_listenForNextRequest = new AutoResetEvent(false);
}
public HttpListener Listener { get { return _listener; } }
public AutoResetEvent ListenForNextRequest { get { return _listenForNextRequest; } }
}
public void ListenAsynchronously(IEnumerable<string> prefixes)
{
HttpListener listener = new HttpListener();
foreach (string s in prefixes)
{
listener.Prefixes.Add(s);
}
listener.IgnoreWriteExceptions = true;
listener.Start();
HttpListenerCallbackState state = new HttpListenerCallbackState(listener);
ThreadPool.QueueUserWorkItem(Listen, state);
}
public void StopListening()
{
stopEvent.Set();
}
private void Listen(object state)
{
HttpListenerCallbackState callbackState = (HttpListenerCallbackState)state;
while (callbackState.Listener.IsListening)
{
callbackState.Listener.BeginGetContext(new AsyncCallback(ListenerCallback), callbackState);
int n = WaitHandle.WaitAny(new WaitHandle[] { callbackState.ListenForNextRequest, stopEvent });
if (n == 1)
{
// stopEvent was signalled
callbackState.Listener.Stop();
break;
}
}
}
private void ListenerCallback(IAsyncResult ar)
{
HttpListenerCallbackState callbackState = (HttpListenerCallbackState)ar.AsyncState;
HttpListenerContext context = null;
int requestNumber = Interlocked.Increment(ref requestCounter);
try
{
context = callbackState.Listener.EndGetContext(ar);
}
catch (Exception ex)
{
return;
}
finally
{
callbackState.ListenForNextRequest.Set();
}
if (context == null) return;
HttpListenerRequest request = context.Request;
// add Proxy and network credentials
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(request.Url.AbsoluteUri);
// get response
HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
Stream responseOut = context.Response.OutputStream;
int CopyByte = CopyStream(response, responseOut);
responseOut.Close();
}
}
}