笔者近期作的服务器监控UWP小程序,结果发如今UWP程序的.NET命名空间下取消了Ping的部分,看了诸多资料,以为多是.NET 4.5 Framework 暂时不支持ICMP。因而笔者想着经过Socket(命名空间保留了的部分)走上层模拟Ping请求,不过这种方式并不能彻底达到效果,缘由在于Socket创建链接是须要终结点的,即IP+端口号,而实际上ICMP请求是不须要端口号的,直接经过发送ICMP询问报文获取服务器状态便可。web
摘记笔者实现的简易Ping方法:小程序
/// <summary> /// 以数据报的消息格式请求链接服务器 /// </summary> /// <param name="desEndPoing">终结点</param> /// <returns></returns> public static async Task<Tuple<string, string, string, string>> DatagramSocketConnect(IPEndPoint desEndPoing) { // 请求状态 string requestStatus = ""; // 请求耗时 string requestCost = ""; // 请求结果 string color = ""; // 请求的额外信息 string others = ""; // 用来记录请求耗时 var s = new System.Diagnostics.Stopwatch(); s.Start(); try { // 使用数据报进行消息传输 using (var UdpClient = new DatagramSocket()) { // 超时控制 CancellationTokenSource cts = new CancellationTokenSource(); cts.CancelAfter(1000); // HostName 构造须要一个主机名orIP地址(不带http!) // 异步创建链接 await UdpClient.ConnectAsync( new Windows.Networking.HostName(desEndPoing.Address.ToString()), desEndPoing.Port.ToString()) // 做为Task任务,添加超时令牌 .AsTask(cts.Token); // 停表 s.Stop(); var remoteIp = UdpClient.Information.RemoteAddress; Debug.WriteLine(String.Format("Success, remote server contacted at IP address {0},and the connecting work cost {1} millsseconds!", remoteIp, s.ElapsedMilliseconds)); #region 修改返回数据 requestStatus = "200"; requestCost = s.ElapsedMilliseconds.ToString(); color = "green"; others = String.Format("Success, remote server contacted at IP address {0},and the connecting work cost {1} millsseconds!", remoteIp, s.ElapsedMilliseconds); #endregion // 释放链接 UdpClient.Dispose(); return new Tuple<string, string, string, string>(requestStatus, requestCost, color, others); } } // 捕获自定义超时异常 catch (TaskCanceledException) { #region 修改返回数据 requestStatus = "1000"; requestCost = s.ElapsedMilliseconds.ToString(); color = "orange"; others = "Error: Timeout when connecting (check hostname and port)"; #endregion return new Tuple<string, string, string, string>(requestStatus, requestCost, color, others); } // 捕获常见的异常 catch (Exception ex) { s.Stop(); // 查不到对应HostName的服务器 if (ex.HResult == -2147013895) { #region 修改返回数据 requestStatus = "0"; requestCost = s.ElapsedMilliseconds.ToString(); color = "red"; others = "Error: No such host is known"; #endregion Debug.WriteLine("Error: No such host is known"); } // 请求超时 else if (ex.HResult == -2147014836) { #region 修改返回数据 requestStatus = "1000"; requestCost = s.ElapsedMilliseconds.ToString(); color = "orange"; others = "Error: Timeout when connecting (check hostname and port)"; #endregion Debug.WriteLine("Error: Timeout when connecting (check hostname and port)"); } // 其余异常 else { #region 修改返回数据 requestStatus = "0"; requestCost = s.ElapsedMilliseconds.ToString(); color = "red"; others = "Error: Exception returned from network stack: " + ex.Message; #endregion Debug.WriteLine("Error: Exception returned from network stack: " + ex.Message); } return new Tuple<string, string, string, string>(requestStatus, requestCost, color, others); } }
上述实现方式中几个重要须要注意的点:windows
上面笔者是用的DatagramSocket实现的,实际上还有不少种Socket也能够实现:MessageWebSocket、StreamSocket等等api
OK,就先记录到这!服务器