C# 如何使用httpc正确回收我的TCP端口

C# 如何使用httpc正确回收我的TCP端口,c#,http,tcp,tcplistener,httplistener,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); } } 这并没有使行为发生任何明显的变化 web日志中唯一出现的另一件事是关于

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

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

foreach (string item in myWebListener.Prefixes) {
    if (item.Contains("http://127.0.0.1:5000")) {
        myWebListener.Prefixes.Remove(item);
    }
}
这并没有使行为发生任何明显的变化

web日志中唯一出现的另一件事是关于favicon.ico文件的内容,可能另一个浏览器线程正在捕获我的连接,试图检索该文件,并将其作为异步回调来完成,虽然我没有提供它,但这种思路对我来说很有意义。如何在字节流中提供favicon.ico文件作为嵌入式资源是我的下一个研究项目

如果这没有改变,我的下一个研究项目将尝试利用TCPListener:

我遇到了这个问题,但它确实没有帮到我,因为我不熟悉我在这里所做的TCP方式,并且所做的工作看起来与我在原始代码中已经尝试过的类似

在链接的Q/a中提到一个using语句,我猜它看起来像:

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; }
}

但是在第一次之后,我完全锁定了浏览器网页,等待新的响应-你是说浏览器发送Http请求但没有响应时出现错误

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


正如其他响应者所说,这不是HttpListener的正常模式,我猜您在服务器上的TCP端口缓存方面有问题,您的.Stop和.Close方法无法释放TCP端口Windows缓存它

我的具体问题实际上是浏览器发出的favicon.ico文件请求锁定了连接

早些时候,我注意到我的服务器被攻击了两次,这就是为什么我在适当的位置设置了我的标志,以确保我只对基于我期望的URL的实际Get请求进行操作

否则URL会出错,因为一个空白字符串证明这是favicon.ico请求-令人恼火,因为当字符串完全为空时,您不知道如何对其进行故障排除。所以我忽略了它,没有触及我不理解的东西

看来我不能忽略这个请求,因为浏览器期待它的响应。我所要做的就是在代码中放置一个else部分,如果我的标志选项不满足,则执行该部分,并在发生这种情况时关闭、处理和刷新连接

这确实很好地描述了问题的固化解决方案,但我的例外。消息是空白的,也没有真正在那里得到解决,所以我很高兴能在这里记录下来,希望任何其他可能遇到相同问题的人都能找到更难解决的答案

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

然而,我不能真正使用这个用户建议的工具,但找到了一个谷歌Chrome内置的替代方案chrome://net-internals/. 只需在chrome中的地址栏中键入并执行它


不管怎样,这是我的全部答案,但是PhillipH你应得的是让我走对的方向。我认为你做事的方式与人们通常做的不同。通常,在Main中有一个无止境的循环等待请求,并为每个请求创建一个线程限制线程并让线程处理请求。或者让您的生活更轻松,请查看webapi@Mightee我仅限于API的实现,而此代码实际上是外接程序的一部分。我可以使用各种标准的web服务器,但我特别需要它与运行它的软件一起运行和消亡,所以。。。这个评论对我没有什么帮助。此外,HttpListener是一个众所周知的.NET模块
,它已经存在了很长一段时间,知识渊博的人都理解它,。哇,你真的不好。无论如何,正如我在前面的评论中提到的,如果你想处理多个请求,你应该做一个无止境的循环。检查这个问题:似乎在processRequests的末尾缺少BeginGetContext。因为你只调用一次,回调只会被触发一次。@Mightee,我不喜欢听到我的声明对你来说意味着什么,因为我只是想说,在这种情况下,这不是一种我很愿意放弃的方法。这个答案对我非常有帮助,因为它让我看到了一些问题;然而,它并没有完全回答我最初的问题。如何实际刷新端口取消阻止我的服务器/杀死并回收我的端口/等等。。。。我在其中运行的API不允许运行多个线程,因此我必须处理我问题的阻塞方面。