UWP simulates Ping request server status

  The author recently made a server monitoring UWP applet. It turned out that the Ping part was canceled in the .NET namespace of the UWP program. After reading a lot of information, I thought that it might be that the .NET 4.5 Framework does not support ICMP for the time being. So I thought about going to the upper layer to simulate the Ping request through the Socket (the part reserved in the namespace), but this method can not fully achieve the effect, because the Socket connection requires an endpoint, that is, IP + port number, but in fact ICMP The request does not require a port number, and the server status can be obtained directly by sending an ICMP query message.

  An excerpt from the simple Ping method implemented by the author:

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

  There are several important points to note in the above implementation:

  • Method body asynchronous (async + await)
  • Exception capture processing (there may be exceptions that the author has not caught)
  • The author's code has added artificial timeout judgment. In fact, using DatagramSocket will have its own timeout judgment, which is about 5s.

  The author above is implemented by DatagramSocket . In fact, there are many kinds of Sockets that can also be implemented: MessageWebSocket , StreamSocket , etc.

OK, just record it here!

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325527294&siteId=291194637
UWP