C# HttpListener 的使用方法
关于监听回调两次的原因,可能是因为重新监听导致的,所以查到微软上面的解析是说
BeginGetContext方法开始异步 (非阻塞) 调用以接收传入的客户端请求。 在调用此方法之前,必须调用 Start 方法,并添加至少一个统一资源标识符 (uri) 前缀,以便通过将 uri 字符串添加到属性返回的来侦听 HttpListenerPrefixCollection Prefixes 。
必须通过调用方法完成异步操作 EndGetContext 。 通常,方法由 callback
委托调用。
操作完成时,此方法不会被阻止。 若要获取传入请求并在操作完成之前一直阻止,请调用 GetContext 方法。
有关使用异步编程模型的详细信息,请参阅 以异步方式调用同步方法
我的猜测是这个
下面是写的一个HttpListener 帮助类
public class HttpListenerServer : IDisposable { private readonly HttpListener _listener; public HttpListenerServer(string[] prefixes) { // 检查系统是否支持 if (!HttpListener.IsSupported) { throw new ArgumentException("使用 该功能的系统 必须为 Windows XP SP2 或 Server 2003 以上系统!"); } if (prefixes == null || prefixes.Length == 0) { throw new ArgumentException("请填写监听地址"); } _listener = new HttpListener(); foreach (string s in prefixes) { _listener.Prefixes.Add(s); } _listener.Start(); _listener.BeginGetContext(new AsyncCallback(GetContextCallBack), _listener); } public void Dispose() { try { if (_listener != null) { _listener.Stop(); _listener.Close(); _listener.Abort(); } RequestHandlerEven = null; } catch (Exception) { } } public delegate object RequestHandler(HttpListenerRequest request); public event RequestHandler RequestHandlerEven; private void GetContextCallBack(IAsyncResult ar) { try { HttpListener httplis = ar.AsyncState as HttpListener; if (httplis.IsListening) { HttpListenerContext context = httplis.EndGetContext(ar); #region 解析Request请求 object resData = null; HttpListenerRequest request = context.Request; if (RequestHandlerEven != null) { resData = RequestHandlerEven(request); } else { resData = new { code = "200", description = "成功", data = "接收数据完成,时间:=" + DateTime.Now }; } #endregion 解析Request请求 #region 构造Response响应 using (HttpListenerResponse response = context.Response) { response.ContentEncoding = Encoding.UTF8; response.ContentType = "application/json;charset=UTF-8"; response.AppendHeader("Content-Type", "application/json;charset=UTF-8"); try { response.StatusCode = (int)HttpStatusCode.OK; string responseString = JsonConvert.SerializeObject(resData, new JsonSerializerSettings() { StringEscapeHandling = StringEscapeHandling.EscapeNonAscii }); using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8)) { writer.Write(responseString); writer.Close(); response.Close(); } } catch (Exception ex) { response.StatusCode = (int)HttpStatusCode.NotFound; response.StatusDescription = "404"; Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($"在接收数据时发生错误:{ex.ToString()}"); //把服务端错误信息直接返回可能会导致信息不安全,此处仅供参考 var returnByteArr = Encoding.UTF8.GetBytes($"在接收数据时发生错误:{ex.ToString()}");//设置客户端返回信息的编码 using (var stream = response.OutputStream) { //把处理信息返回到客户端 stream.Write(returnByteArr, 0, returnByteArr.Length); stream.Close(); response.Close(); } } } #endregion 构造Response响应 httplis.GetContext(); _listener.BeginGetContext(new AsyncCallback(GetContextCallBack), _listener); } } catch (Exception ex) { throw new ArgumentException(ex.Message); } } }