未捕获的监听器异常

后端开发 2026-07-08

这里展示的代码存在一些问题。我将其分为三种情况,并对失败的情况做更详细的解释。

情况1:当网络链路处于不可用状态(DOWN)时,代码未从路由器获取IP——因此未发送数据,也不会抛出异常。

情况2:当网络链路处于可用状态(UP)时,代码从路由器获取到了IP——因此数据正在发送。

情况3:当网络链路再次处于不可用状态时,post方法尝试发送数据,但失败并抛出未捕获的异常:

++++ Exception System.Net.Sockets.SocketException - CLR_E_FAIL (1) ++++
++++ Message: 
++++ System.Net.Sockets.NativeSocket::poll [IP: 0000] ++++
++++ System.Net.Sockets.Socket::Poll [IP: 0011] ++++
++++ System.Net.Sockets.Socket::Connect [IP: 002b] ++++
++++ System.Net.HttpWebRequest::EstablishConnection [IP: 0192] ++++
++++ System.Net.HttpWebRequest::SubmitRequest [IP: 001a] ++++
++++ System.Net.HttpWebRequest::GetRequestStream [IP: 0008] ++++
++++ System.Net.Http.HttpMessageInvoker::Send [IP: 0013] ++++
++++ System.Net.Http.HttpClient::Send [IP: 006f] ++++
++++ System.Net.Http.HttpClient::Post [IP: 0011] ++++
++++ FourGNano.EthernetNet::Post [IP: 002d] ++++

由于这是未捕获的异常,程序不会直接结束,我无法进行清理,也无法再次发送数据。

请指出我代码中的错误:

using nanoFramework.Hardware.Esp32;
using System;
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace NFSocket
{
    public class Program
    {
        /// <summary>
        /// 
        /// </summary>
        public static void Main()
        {
            Debug.WriteLine("Hello from nanoFramework!");

            NetworkChange.NetworkAvailabilityChanged += Program.NetworkAvailabilityChanged;
            //NetworkChange.NetworkAvailabilityChanged += EthernetNet.NetworkAddressChanged;

            int _count = 0;

            for (; ; )
            {
                _count++;

                nanoFramework.Runtime.Native.GC.Run(true);

                if (Program.GetLocalIPAddress())
                {
                    Thread.Sleep(2000);

                    //string _url = "http://192.168.0.100:7091/p/1234/1234/info/g-startup/1";

                    string _url = "http://hes.lightmee.in/p/1234/1234/info/g-startup/1";

                    string _result = Program.Post(_url, "1234");

                    if (!string.IsNullOrEmpty(_result) && _result.Contains("202"))
                    {
                        Console.WriteLine("Data Posted");
                    }
                }
                else
                {
                    Console.WriteLine("NO IP");
                }

                Thread.Sleep(10000);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public static void NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
        {
            if (e.IsAvailable)
            {
                Console.WriteLine("Ethernet Link UP");
                //EthernetNet.Start_Listening();
            }
            else
            {
                Console.WriteLine("Ethernet Link DOWN");
                //Program.Stop_Listening();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static bool GetLocalIPAddress()
        {
            //var host = Dns.GetHostEntry(Dns.GetHostEntry());
            var host = NetworkInterface.GetAllNetworkInterfaces();

            if (host != null)
            {
                foreach (NetworkInterface ni in host)
                {
                    //Console.WriteLine("IP Address : " + ni.IPv4Address);

                    if (ni.IPv4Address != "0.0.0.0")
                    {
                        Console.WriteLine("IP Address : " + ni.IPv4Address);

                        EthernetNet.IsEthernetConnected = true;

                        return true;
                    }
                }
            }

            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pData"></param>
        public static string Post(string pUrl, string pData)
        {
            HttpClient _httpClient = null;
            HttpResponseMessage _r = null;

            try
            {
                //check the connectivity, contents and data to post it
                if (Program.GetLocalIPAddress() && !string.IsNullOrEmpty(pUrl) && !string.IsNullOrEmpty(pData))
                {
                    Thread.Sleep(2000);

                    _httpClient = new();

                    _r =  _httpClient.Post(pUrl, new StringContent(pData));

                    _r.EnsureSuccessStatusCode();

                    HttpStatusCode _sc = _r.StatusCode;

                    _r.Dispose();
                    _httpClient.Dispose();

                    if (_sc == HttpStatusCode.Accepted || _sc == HttpStatusCode.Created)
                    {
                        return "202";
                    }
                }
            }
            catch (System.Net.Http.HttpRequestException pEx)
            {
            }
            catch (System.Net.Sockets.SocketException pEx)
            {
                ///Helper.Handle_Exception("Ethernet-Post", pEx);
            }
            catch (Exception pEx)
            {
                //Helper.Handle_Exception("Ethernet-Post", pEx);
            }
            finally
            {
                if (_httpClient != null)
                {
                    _httpClient.Dispose();
                }

                if (_r != null)
                {
                    _r.Dispose();
                }
            }

            return null;
        }
    }
}

解决方案

首先,你应该在整个应用程序生命周期中只实例化一次HttpClient,并在整个生命周期中重复使用它。请参考这里的README,里面有示例:
https://github.com/nanoframework/System.Net.Http#httpclient-calling-rest-services

其次,如果你需要知道连接是否可用,可以检查网络连接状态,而不是查询IPAddress。请参阅:
https://docs.nanoframework.net/api/nanoFramework.Networking.NetworkHelper.html#nanoFramework_Networking_NetworkHelper_Status

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章