如何使用 HttpListener c# 正确回收我的 TCP 端口
How to properly recycle my TCP port using HttpListener c#
根据评论和我自己的测试,我确定我的初始 TCP 端口没有清除,我真的不知道如何补救。
我尝试 运行 在我的刷新方法中通过这样的前缀:
foreach (string item in myWebListener.Prefixes) {
if (item.Contains("http://127.0.0.1:5000")) {
myWebListener.Prefixes.Remove(item);
}
}
这并没有使行为发生任何明显的变化。
Web 日志中唯一弹出的另一件事是关于 favicon.ico 文件的内容,也许另一个浏览器线程正在捕获我的连接,试图检索它并打算将其作为异步回调提供以完成工作,尽管我没有提供它所以这种思路对我来说很有意义(How to provide a favicon.ico file in my byte stream as an嵌入式资源是我的下一个研究项目)。
如果没有变化,我的下一个研究项目将尝试利用 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.
}
这是我的大脑所能想到的最远的距离,根据这里的影响因素,这听起来是不是很遥远?
以下是原问题内容:
我成功连接到我的 运行ning C# HttpListener 本地主机服务器,并成功将信息发送回本地请求浏览器页面。
但是第一次之后,我完全锁定了浏览器网页等待新的响应。
我在 VS 上调试没有错误,所以我什至不知道下一步该看哪里;这就是我来这里的原因。
我希望有人可以阐明如何在内部刷新我的服务器,这样当需要新查询时,我可以像第一次一样响应它。
我正在使用 http get 方法来调用它,因此调用类似于以下内容:
"http://127.0.0.1:5000/?param1=searchForThings¶m2=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; }
}
"But after the first time, I completely lock up the browser web page waiting for a new response" - 你是说在发送 Http 请求但没有得到响应的浏览器上看到错误?
我建议下载并使用 Telerik Fiddler(免费)来查看客户端和服务器之间实际发送和接收的内容。
正如其他回复者所说 - 这不是 HttpListener 的正常模式,我猜你在服务器上遇到 TCP 端口缓存问题,而你的 .Stop() 和 .Close() 方法不是释放 TCP 端口(Windows 缓存它)
我的特殊问题实际上是来自浏览器的 favicon.ico 文件请求锁定了连接。
早些时候我注意到我的服务器被攻击了两次,这就是为什么我设置了标志以确保我只在基于 [=43= 的实际 Get 请求上操作] 我期待...
否则 URL 会错误地显示为空字符串(原来这是 favicon.ico 发出的请求 - 令人恼火,因为当字符串完全为空时你不知道如何解决它).所以我是忽略它,不去碰我不明白的东西。
好吧,我可以 NOT 忽略此请求,因为浏览器需要对它的响应。我所要做的就是在我的代码中放置一个 else 部分,如果我的标志选项不满足则执行该部分,并在发生这种情况时关闭、处理和刷新连接。
这个 Q/A 确实很好地描述了问题的固定解决方案,但是我的 Exception.Message 是空白的,那里也没有真正得到解决,所以我很高兴能记录下来在这里希望任何其他可能 运行 遇到同样问题的人都能找到更简单的答案。
至于 PhillipH 提供的答案,事实证明这对我最有帮助,因为它告诉我我需要检查网络流量事件发生了什么。
但是我无法真正使用该用户建议的工具,但找到了 Google Chrome 内置的替代方法 chrome:// net-internals/。只需在地址栏中输入 chrome 并执行即可。
无论如何,这就是我的全部答案,但 PhillipH 是你让我朝着正确的方向前进,这是你应得的。
根据评论和我自己的测试,我确定我的初始 TCP 端口没有清除,我真的不知道如何补救。
我尝试 运行 在我的刷新方法中通过这样的前缀:
foreach (string item in myWebListener.Prefixes) {
if (item.Contains("http://127.0.0.1:5000")) {
myWebListener.Prefixes.Remove(item);
}
}
这并没有使行为发生任何明显的变化。
Web 日志中唯一弹出的另一件事是关于 favicon.ico 文件的内容,也许另一个浏览器线程正在捕获我的连接,试图检索它并打算将其作为异步回调提供以完成工作,尽管我没有提供它所以这种思路对我来说很有意义(How to provide a favicon.ico file in my byte stream as an嵌入式资源是我的下一个研究项目)。
如果没有变化,我的下一个研究项目将尝试利用 TCPListener:
我 运行 穿过这个
在链接 Q/A 中提到了 using 语句,我猜它看起来像:
using(TCPListener myTCPListener = new TCPListener()) {
//Set the necessary TCP statements here.
//Do what I already did with my existing code here.
}
这是我的大脑所能想到的最远的距离,根据这里的影响因素,这听起来是不是很遥远?
以下是原问题内容:
我成功连接到我的 运行ning C# HttpListener 本地主机服务器,并成功将信息发送回本地请求浏览器页面。
但是第一次之后,我完全锁定了浏览器网页等待新的响应。
我在 VS 上调试没有错误,所以我什至不知道下一步该看哪里;这就是我来这里的原因。
我希望有人可以阐明如何在内部刷新我的服务器,这样当需要新查询时,我可以像第一次一样响应它。
我正在使用 http get 方法来调用它,因此调用类似于以下内容:
"http://127.0.0.1:5000/?param1=searchForThings¶m2=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; }
}
"But after the first time, I completely lock up the browser web page waiting for a new response" - 你是说在发送 Http 请求但没有得到响应的浏览器上看到错误?
我建议下载并使用 Telerik Fiddler(免费)来查看客户端和服务器之间实际发送和接收的内容。
正如其他回复者所说 - 这不是 HttpListener 的正常模式,我猜你在服务器上遇到 TCP 端口缓存问题,而你的 .Stop() 和 .Close() 方法不是释放 TCP 端口(Windows 缓存它)
我的特殊问题实际上是来自浏览器的 favicon.ico 文件请求锁定了连接。
早些时候我注意到我的服务器被攻击了两次,这就是为什么我设置了标志以确保我只在基于 [=43= 的实际 Get 请求上操作] 我期待...
否则 URL 会错误地显示为空字符串(原来这是 favicon.ico 发出的请求 - 令人恼火,因为当字符串完全为空时你不知道如何解决它).所以我是忽略它,不去碰我不明白的东西。
好吧,我可以 NOT 忽略此请求,因为浏览器需要对它的响应。我所要做的就是在我的代码中放置一个 else 部分,如果我的标志选项不满足则执行该部分,并在发生这种情况时关闭、处理和刷新连接。
这个 Q/A 确实很好地描述了问题的固定解决方案,但是我的 Exception.Message 是空白的,那里也没有真正得到解决,所以我很高兴能记录下来在这里希望任何其他可能 运行 遇到同样问题的人都能找到更简单的答案。
至于 PhillipH 提供的答案,事实证明这对我最有帮助,因为它告诉我我需要检查网络流量事件发生了什么。
但是我无法真正使用该用户建议的工具,但找到了 Google Chrome 内置的替代方法 chrome:// net-internals/。只需在地址栏中输入 chrome 并执行即可。
无论如何,这就是我的全部答案,但 PhillipH 是你让我朝着正确的方向前进,这是你应得的。