如何使用HttpListener c#

时间:2018-02-16 20:09:30

标签: c# http tcp tcplistener httplistener

根据评论和我自己的测试,我确信我的初始TCP端口没有清除,我真的不知道如何解决它。

我尝试在刷新方法中运行这样的前缀:

foreach (string item in myWebListener.Prefixes) {
    if (item.Contains("http://127.0.0.1:5000")) {
        myWebListener.Prefixes.Remove(item);
    }
}

这并没有对行为做出任何明显的改变。

网络日志中出现的唯一另一件事是关于 favicon.ico 文件,而且可能是另一个浏览器线程正在捕获我的连接,试图检索这个并打算提供它作为一个异步回调来完成任务,虽然我没有提供它所以这个思路对我有意义(如何在我的字节流中提供一个favicon.ico文件作为嵌入式资源是我的下一个研究项目)。

如果这显示没有变化,我的下一个研究项目是尝试利用TCPListener:

我遇到了这个Q/A,但它确实没有帮助我,因为我不熟悉我在这里做的事情的TCP方式,而且解决方案看起来与我的相似我已经尝试使用原始代码了。

在链接的Q / A中提到了一个使用声明,我的猜测是它看起来像:

using(TCPListener myTCPListener = new TCPListener()) {
    //Set the necessary TCP statements here.
    //Do what I already did with my existing code here.
}

就我的大脑而言,到目前为止,这听起来远远不是基于这里发挥的因素吗?

以下是原始问题内容

我成功到达正在运行的C#HttpListener localhost服务器,并成功将信息发送回本地请求浏览器页面。

但是在第一次之后,我完全锁定了浏览器网页,等待新的响应。

我在VS上没有任何错误进行调试,所以我甚至不知道接下来要去哪里看看;因此,这就是我在这里的原因。

我的希望是,有人可以了解如何在内部刷新我的服务器,所以当需要新查询时,我可以像第一次那样回复它。

我使用http get方法调用此方法,因此调用类似于以下内容:

"http://127.0.0.1:5000/?param1=searchForThings&param2=itemToSearchFor";

我必须删除许多专有代码,但现在正在发生的事情:

public class myWebServer {
    public myWebServer() {
            refresh();
            //The Global is being set When the API 
            //  Loads & is referenced here
            ev1 = _MyGlobalEvents.ev1
    }

    public static HttpListener myWebListener { get; set; }
    public static HttpListenerContext context { get; set; }
    public static AsyncCallback myGetCallback { get; set; }
    public static HttpResponseMessage myResp { get; set; }
    public static Stream output { get; set; }
    public static MyAPIDefinedEventType ev1 { get; set; }

    public static void refresh() {
        if (myWebListener != null) {
                myWebListener.Stop();
                myWebListener.Close();
        }
        if (output != null) { output.Dispose(); }
        if (myGetCallback != null) { myGetCallback = null; }
        myWebListener = new HttpListener();
        myGetCallback = new AsyncCallback(processRequest);
        myWebListener.Prefixes.Add("http://127.0.0.1:5000/");
        myWebListener.Start();
        myResp = new HttpResponseMessage(HttpStatusCode.Created);
        myWebListener.BeginGetContext(myGetCallback, myResp);
    }

    public static void processRequest(IAsyncResult result) {
        context = myWebListener.EndGetContext(result);
        context.Response.KeepAlive = true;
        myResp = new HttpResponseMessage(HttpStatusCode.Accepted);
        context.Response.StatusCode = (int)HttpStatusCode.Accepted;
        output = context.Response.OutputStream;
        string label = context.Request.QueryString["param1"];
        string fiStr = context.Request.QueryString["param2"];

        if (label != null || label != "" || label.Contains("\n") == false) {
            int pass1 = 0;
            int pass2 = 0;
            try {
                int myInt = label.ToCharArray().Length;
                pass1 = 1;
            } catch { }
            if (pass1 > 0) {
                try {
                    int myInt2 = fiStr.ToCharArray().Length;
                    pass2 = 1;
                } catch { }
            }
            if ((pass1 == 1 && pass2 == 0) || (pass1 == 1 && pass2 == 1)) {
                pass1 = 0;
                pass2 = 0;
                if (label == "searchForThings" && (fiStr != null && fiStr != "")) {
                    string respStr = "<html><body><div id=\"status_msg\" style=\"display:inline;\">" + fiStr + "</div></body></html>";
                    byte[] respBuffer = Encoding.ASCII.GetBytes(respStr);
                    context.Response.StatusCode = (int)HttpStatusCode.Accepted;
                    output.Write(respBuffer, 0, respBuffer.Length);
                    _MyGlobalEvents.searchStr = fiStr;
                    ev1.Raise();
                }
            }
        }
    }

    //When the Custom Event is done processing it runs something like the 
    //following to clean up and finalize
    public void _processSearch(string resultStr) { processSearch(resultStr); }
    public static void processSearch(string resultStr) {
        string respStr = "<html><head>" +
                        "<style type=\"text/css\">" +
                        "tr.dispRow{ display:table-row; }\n" +
                        "tr.noRow{ display:none; }" +
                        "</style>" +
                        "</head>" +
                        "<body>" +
                        resultStr +
                        "</body></html>";
        byte[] respBuffer = Encoding.ASCII.GetBytes(respStr);
        output.Flush();
        context.Response.StatusCode = (int)HttpStatusCode.OK;
        output.Write(respBuffer, 0, respBuffer.Length);
        output.Close();
        context.Response.KeepAlive = false;
        context.Response.Close();
        refresh();
    }
}

public static class _MyGlobalEvents {
    public static string searchStr { get; set; }
    public static MyAPIDefinedEventType ev1 { get; set; }
}

2 个答案:

答案 0 :(得分:1)

“但是在第一次之后,我完全锁定浏览器网页等待新的响应” - 你是说在发送Http请求的浏览器上看到错误但没有得到响应?

我建议下载并使用Telerik Fiddler(免费)查看客户端和服务器之间实际发送和接收的内容。

正如其他受访者所说 - 这不是HttpListener的正常模式,我猜你在服务器上遇到TCP端口缓存问题,你的.Stop()和.Close()方法没有释放TCP端口(Windows缓存它)

答案 1 :(得分:0)

我的特殊问题实际上是来自浏览器锁定连接的 favicon.ico 文件请求。

早期我注意到我的服务器被击中两次,这就是为什么我有我的标志,以确保我只是根据我期望的URL操作实际的Get请求。

否则URL错误地显示为空白字符串(原来这是favicon.ico请求正在制作 - 令人生气,因为当字符串完全为空时您不知道如何对其进行故障排除)。所以我忽略了它而没有触及我不理解的东西。

好吧,我可以忽略此请求,因为浏览器期待它的响应。我所要做的就是在我的代码中添加 else 部分,如果我的标记选项未满足则执行,并在发生这种情况时关闭,处理并刷新连接。

这个Q/A确实很好地描述了问题的巩固解决方案,但我的Exception.Message是空白的,也没有真正得到解决,所以我很高兴我得到文件希望任何可能遇到同样问题的人都能找到更加紧张的答案。

至于PhillipH提供的答案,这对我来说是最有帮助的,因为它告诉我,我需要检查网络流量事件发生的情况。

但是,我无法真正使用此用户建议的工具,但找到​​了Google Chrome内置 chrome:// net-internals / 的替代方案。只需在chrome中输入地址栏并执行即可。

无论如何,这对我来说是完全的答案,但PhillipH你应该让我朝着正确的方向前进。