繁体   English   中英

HttpListener的C#问题

[英]C# problem with HttpListener

我使用HttpListener编写了一个Windows服务,以异步方式处理来自点的请求。

它工作正常,但有时它遇到一个问题,需要重新启动服务或服务器来修复。 最初我用以下方法声明了侦听器对象:

public HttpListener PointsListener = new HttpListener();

这是我开始收听的方法的代码。 我是从服务的OnStart方法调用它:

    public string ListenerStart()
    {
        try
        {
            if (!PointsListener.IsListening)
            {
                PointsListener.Prefixes.Add(String.Concat("http://*:", points_port, "/"));
                PointsListener.Start();
                PointsListener.BeginGetContext(PointProcessRequest, PointsListener);

                LogWriter("Http listener activated on port " + points_port);
                return "Listener started";
            }
            else
            {
                return "Listener is already started!";
            }

        }
        catch (Exception err)
        {
            LogWriter("Error in LIstenerStart \r\n" + err.ToString());
            return ("Error: " + err.Message);
        }
    }

以下是处理请求的方法:

    private void PointProcessRequest(IAsyncResult result)
    {
        HttpListener listener = (HttpListener)result.AsyncState;
        HttpListenerContext context = listener.EndGetContext(result);
        HttpListenerRequest request = context.Request;
        HttpListenerResponse response = context.Response;
        response.KeepAlive = false;
        System.IO.Stream output = response.OutputStream;

        try
        {
            //declaring a variable for responce
            string responseString = "<html>My Response: request is not allowed by server protocol</html>";


            // Commands and actions to set responceString

            byte[] buffer = Encoding.UTF8.GetBytes(responseString);
            response.ContentLength64 = buffer.Length;
            output.Write(buffer, 0, buffer.Length);
        }
        catch (Exception err)
        {
            LogWriter("Error in PointProcessRequest: \r\n" + err.ToString());
        }
        finally
        {
            try
            {
                output.Flush();
                output.Close();
                response.Close();
            }
            catch (Exception err)
            {
                LogWriter("Error in PointProcessRequest CLOSING OUTPUT STREAM: \r\n" + err.ToString());
            }
            finally
            {
                PointsListener.BeginGetContext(PointProcessRequest, PointsListener);
            }
        }
    }

它在某些时候运行良好,但日志中出现以下错误:

Error in PointProcessRequest: 
System.Net.HttpListenerException: The specified network name is no longer available
   в System.Net.HttpResponseStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   в ARK_Dealer.ark.PointProcessRequest(IAsyncResult result)

[26.01.2011 9:00:54] Error in PointProcessRequest CLOSING OUTPUT STREAM: 
System.InvalidOperationException: Cannot close stream until all bytes are written.
   в System.Net.HttpResponseStream.Dispose(Boolean disposing)
   в System.IO.Stream.Close()
   в ARK_Dealer.ark.PointProcessRequest(IAsyncResult result)

我认为当某个点将请求发送到服务器但在接收应答失去连接之前出现问题。

如何防止抛出异常? 响应对象会被自动妥善处理吗? 我该如何解决这个问题?

我正在生产中使用HttpListener,我找到了解决这个问题的最好方法,而没有添加一大堆try / catch块,它们无法传达手头代码的逻辑; 是非常简单地设置Listener.IgnoreWriteExceptions = true; 而且,瞧不再写异常了!

有一个相关的问题

你正在做的很好,因为关闭连接或连接被丢弃的另一方没有其他任何事情可以做。 您可能希望捕获确切的异常并调用output.Dispose()和其他清理,或者只是让终结器处理释放,如果它不经常发生的话。

我最近遇到了同样的问题,并通过将输出包装在try / catch中来解决它:

try
{
    byte[] buffer = Encoding.UTF8.GetBytes(responseString);
    response.ContentLength64 = buffer.Length;
    output.Write(buffer, 0, buffer.Length);
}
catch (HttpListenerException)
{
    // Handle error caused by connection being lost
}

问题解决了!!! 我刚删除了这个:

finally
{
PointsListener.BeginGetContext(PointProcessRequest, PointsListener);
}

并在PointProcessRequest方法的开头插入此命令!

IAsyncResult _result = listener.BeginGetContext(new AsyncCallback(PointProcessRequest), listener);

问题解决了100%!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM