Windows CE 5中的C#应用程序最终崩溃

Windows CE 5中的C#应用程序最终崩溃,c#,sockets,udp,compact-framework,windows-ce,C#,Sockets,Udp,Compact Framework,Windows Ce,我已经用C#(.NETCompactFramework2.0)编写了一个使用UDP套接字的非常基本的应用程序 这个程序可以正常运行一段时间(一次最多几个星期),但最终总是失败。除了我的客户端无法重新连接之外,此错误似乎会对关联NIC的所有活动造成负面影响。一旦发生这种情况,我就不能再远程进入设备(使用CE remote Display)——这是我获得额外调试反馈的唯一方法。因此,在这一点上,我不能100%确定应用程序本身是否崩溃,或者我正在通过套接字代码破坏操作系统中的某些东西 我实现了一个从未

我已经用C#(.NETCompactFramework2.0)编写了一个使用UDP套接字的非常基本的应用程序

这个程序可以正常运行一段时间(一次最多几个星期),但最终总是失败。除了我的客户端无法重新连接之外,此错误似乎会对关联NIC的所有活动造成负面影响。一旦发生这种情况,我就不能再远程进入设备(使用CE remote Display)——这是我获得额外调试反馈的唯一方法。因此,在这一点上,我不能100%确定应用程序本身是否崩溃,或者我正在通过套接字代码破坏操作系统中的某些东西

我实现了一个从未引发的未处理异常事件。我还有许多try/catch块,它们将异常消息输出到文本文件。我没有看到任何异常被抛出

///删除旧的TCP代码

客户端本身是配置为UDP服务器的简单小型网关设备。这是一个远程系统,我可以少用它,虽然我有一个测试控制器和网关单元,但条件不同,我还不能重现我这边的问题

TIA的任何反馈

编辑:

我一直在运行我的测试台演示,并根据一些评论建议定期检查服务器上的netstat。在CE5中,netstat不接受-a标志,所以我一直在使用-n(不确定这是否会告诉我需要什么…)。我已经多次断开和重新连接我的客户端,通过拔下以太网等方式强制打开了一半。netstat表只显示每个客户端(在适当的端口)的一个连接

编辑2:


由于生产过程中消息传递的稀疏性,我将应用程序改为无连接的UDP消息传递,但我仍然遇到相同的行为(发生故障的时间大致相同)。在我的测试硬件上,应用程序以高消息率(每隔几秒钟一次)无限期地成功运行。然而,在生产环境中,消息的频率要低得多,程序在运行大约10天后就会失败。我认为不采取行动并不重要,但也许我错了?寻找我能得到的任何建议

新的发送/接收代码:

    public void Send(string Message)
    {
        Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        EndPoint ep = new IPEndPoint(IPAddress.Parse(_ipAddress), _port);

        udpClient.Connect(ep);

        byte[] data = Encoding.ASCII.GetBytes(Message);
        // async send, sync receive
        udpClient.BeginSendTo(data, 0, data.Length, SocketFlags.None, ep, (ar) =>
        {
            try
            {
                udpClient.EndSendTo(ar);
                _lastSent = Message;

                string msg = this.ReceiveSync(udpClient, 3);
                if (!string.IsNullOrEmpty(msg))
                {
                    _lastReceived = msg;
                    DataReceived(new ReceiveDataEvent(_lastReceived));
                }
            }
            catch { }
            finally
            {
                udpClient.Close();
            }

        }, null);
    }

    private string ReceiveSync(Socket UdpClient, int TimeoutSec)
    {
        string msg = "";
        byte[] recBuffer = new byte[256];

        int elapsed = 0;
        bool terminate = false;
        do
        {
            // check for data avail every 500ms until TimeoutSecs elapsed
            if (UdpClient.Available > 0)
            {
                int bytesRead = UdpClient.Receive(recBuffer, 0, recBuffer.Length, SocketFlags.None);
                msg = Encoding.ASCII.GetString(recBuffer, 0, recBuffer.Length);
                terminate = true;
            }
            else
            {
                if ((elapsed / 2) == TimeoutSec) 
                    terminate = true;
                else
                {
                    elapsed++;
                    System.Threading.Thread.Sleep(500);
                }
            }
        } while (!terminate);

        return msg;
    }

服务器(Windows CE 5,32位操作系统)上的套接字可能已用完。请参见第页的类似内容。“…一旦TCP套接字关闭(默认情况下),端口将在TIMED_WAIT状态下保持占用状态2分钟…”

我缺少关于每次有多少客户端创建/关闭连接的信息。 您可能需要考虑套接字选项,以便重新使用eaddr()

您可以在服务器子网中执行循环网络跟踪(30分钟左右,刚好有机会看到之前发生的情况,这取决于“崩溃”后停止跟踪的速度),以查看“崩溃”之前发生的情况

另一个问题是定期(夜间)重新启动服务器,因为所有Windows Mobile CE设备都不能全天候正常运行

我们的客户使用大量Windows嵌入式手持6.5(基于CE5)设备。即使它们没有太多的网络,这些设备在一天中工作最稳定,如果它们每晚重新启动的话。 定期重启也会发现CE5服务器上的NIC驱动程序出现故障(谁知道呢,有些公司在平台软件方面做得不好)。或者尝试其他供应商的NIC


顺便说一句:我已经为Windows Mobile编写了自己的netstat:。我没有在Windows CE5上测试它,但它应该可以工作,或者也可以在CE5上工作。

您在异步回调中执行异常处理吗?是否会这样,您正在占用所有可用端口?(通过在不断开连接的情况下重新连接)因为“杀死NIC上的所有活动”对我来说是闻所未闻的。TCP自20世纪70年代首次开发以来就存在一个众所周知的问题。我相信你有一个半开半关的连接。您可以从cmd.exe>Netstat-a(在客户端和服务器上运行)进行验证。您的连接未完全关闭,因此无法建立新连接。问题是当您关闭连接时,TCP需要ACK,并且除非您获得ACK,否则连接不会关闭。当您同时关闭来自客户端和服务器的连接时,其中一个会收到ACK,另一个不会收到ACK。始终只关闭来自客户端的连接。从服务器上删除关闭。@jdweng我可以看出这是一个特定客户端的问题,但我不明白这如何会导致控制器完全停止接收连接(在特定NIC上)。不过,我非常感谢您提供的信息-我会修改的。不客气。请呆在家里,注意安全。嘿,约瑟夫,谢谢你的回复。只有两个客户端,它们被配置为使用持久TCP连接。因此,我只希望在连接频繁中断或丢失的情况下耗尽套接字。这不是不可能的,因为这是一个工业环境,但仍然出乎意料。只有网络跟踪可能会验证客户端始终使用相同的连接。我将应用程序更改为UDP,并且遇到了相同的行为,失败的时间大致相同。在我的测试中,我能够观察(使用netstat-n)连接的创建和端口分配。这些端口会将每条消息的增量一直增加到65535,然后简单地滚动,继续成功运行。但是,在生产环境中,消息的频率要低得多,应用程序在运行约10天后仍然会失败。有什么想法吗?可能客户端做的事情比您的测试环境更奇怪。最好是使用网络跟踪。