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

问题描述 投票:1回答:1

我已经使用TcpListener类和几个客户端套接字在C#(.NET Compact Framework 2.0)中编写了一个非常基本的应用程序。

该程序可以正常运行一段时间(一次最多几个星期),但最终总是会失败。在我的客户端无法重新连接的基础上,此错误似乎对关联的NIC的all活动造成了不利影响。一旦发生这种情况,我将不再能够远程访问设备(使用CE Remote Display)-这是我获得调试附加反馈的唯一途径。因此,在这一点上,我还不能100%确定应用程序本身是否崩溃,或者是否正在通过套接字代码破坏操作系统中的某些内容。

我实现了一个从未处理过的未处理异常事件。我其余的异常处理当前会写出到GUI(一旦我无法再远程查看它,这将是无用的)。除了更改所有异常以将其记录到文件之外,我还在寻找任何其他信息或见解。

基本TcpListener代码:

_server = new TcpListener(IPAddress.Any, Config.ServerListenPort);
_server.Start();
_server.Server.BeginAccept(new AsyncCallback(OnClientConnected), null);

已连接客户端:

private static void OnClientConnected(IAsyncResult ar)
{
   Socket connected = _server.Server.EndAccept(ar);

   string ip = GetIpString(connected);

   // only accept known clients
   if (_acceptedClientsList.Contains(ip))
   {
      // if client already connected, close and reconnect
      // perhaps there is a better way to do this?
      if (_client != null)
      {
          _client.Close();
          _client = null;
      }

      // set client reference
      _client = connected;

      // start accepting data
      _client.BeginReceive(_tcpBuffer, 0, 256, 0, new AsyncCallback(tcpEndReceive), null);
   }
}

客户收到:

private void tcpEndReceive(IAsyncResult ar)
{
   // get count of read bytes
   int readBytes = _client.EndReceive(ar);
   if ((_client != null) && _client.Connected)
   {
       // readBytes == 0 when client issues disconnect
       if (readBytes > 0)
       {
           // convert read bytes to string
           string read = Encoding.ASCII.GetString(_tcpBuffer, 0, readBytes);

           // data receive notification to owner
           tcpDataReceived(new ReceiveDataEvent(read));

           // listen for more incoming data
           _client.BeginReceive(_tcpBuffer, 0, 256, SocketFlags.None, new AsyncCallback(tcpEndReceive), null);
       }
       else
       {
           // client disconnected
           _client.Close();
           _client = null;

           // client-issued disconnect
           tcpDataReceived(new ReceiveDataEvent("Client voluntarily disconnected."));
       }
    }
}

客户发送:

public void Send(string Message)
{
   if ((_client != null) && _client.Connected)
   {
       // convert string to bytes and send
       byte[] send = Encoding.ASCII.GetBytes(Message);
       _client.Send(send, SocketFlags.None);
   }
}

为了简洁起见,对此进行了简化。我的客户实际上是由另一个包含其他不相关信息的类“节点”管理的-但是每个节点都有一个_client字段,并如图所示进行连接。

客户端本身是简单的小型网关设备,配置为连接到服务器并转发信息。他们还每五分钟发送一次Keepalive消息。

我最初的想法可能是某处内存泄漏,但是我只是在实现一些内存诊断和日志记录。这是一个我可以少量使用的远程系统,尽管我具有测试控制器和网关单元(客户端),但条件并不完全相同,并且我至今还无法重现该问题。

TIA提供任何反馈。

编辑:

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

c# sockets tcp compact-framework windows-ce
1个回答
0
投票

您可能用完了服务器(Windows CE 5,32位OS)上的套接字。参见Is there a limit on number of tcp/ip connections between machines on linux?中的类似内容。 “ ...一旦关闭TCP套接字(默认情况下),该端口将保持处于TIMED_WAIT状态2分钟...”

我缺少有关每次有多少个客户端创建/关闭连接的信息。您可能需要处理套接字选项SO_REUSEADDR(https://docs.microsoft.com/en-us/previous-versions/windows/embedded/ms884940%28v%3dmsdn.10%29)。

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

另一个难点是要定期重新启动服务器(一个晚上),因为所有Windows Mobile CE装置都不能24/7正常运行。

我们的客户使用很多Windows Embedded Handheld 6.5(基于CE5)设备。即使它们没有太多网络,但如果它们每天晚上重新启动,它们在一天中的运行也会最稳定。定期重新启动还会发现CE5服务器上的NIC驱动程序出现故障(谁知道某些公司的Platform软件表现不佳)。或尝试其他供应商的NIC。

BTW:我已经为Windows Mobile编写了自己的netstat:http://www.hjgode.de/wp/2013/09/24/mobile-development-netstat-know-your-devices-open-ports/。我没有在Windows CE5上对其进行测试,但是它应该也可以在CE5上工作。

© www.soinside.com 2019 - 2024. All rights reserved.