【问题标题】:Biometrics device ping becoming failed after sometime生物识别设备 ping 一段时间后失败
【发布时间】:2019-04-30 04:48:25
【问题描述】:

我有 ZKTeco 生物识别设备,它使用 This tutorial (C# ZKTeco Biometric Device Getting Started) 与 C# windows 应用程序连接。

它工作正常,但一段时间后,我的应用程序无法 ping 设备。如下代码所示,我尝试每 25 秒 ping 一次设备。

  private void TimerCheckPingAndCloseAttendanceForm() {
  timerCheckPingAndCloseAttendanceForm            = new Timer();
  timerCheckPingAndCloseAttendanceForm.Tick       += new EventHandler(CheckPingAndCloseAttendanceForm);
  timerCheckPingAndCloseAttendanceForm.Interval   = 25000;//25 seconds.
  timerCheckPingAndCloseAttendanceForm.Start();
        }


 private void CheckPingAndCloseAttendanceForm(object sender, EventArgs e) {
     string ipAddress = tbxDeviceIP.Text.Trim();
     if (UniversalStatic.PingTheDevice(ipAddress) == false) {
           //CloseAttendaceListForm();
           IsDeviceConnected = false;
           string infoString = "Application started on " + applicationStartDateTime.ToString() + " and ping failed on " + DateTime.Now.ToString() + " then, app closed while device ip is "+ ipAddress;
          File.AppendAllText("ConnectionLog.txt", infoString + Environment.NewLine);
          Application.Exit();
          //timerCheckPingAndCloseAttendanceForm.Tick -= new EventHandler(CheckPingAndCloseAttendanceForm);
            }
        }

当我尝试从 cmd ping 命令时,设备显示 destination host is unreachable。但每当我重新启动设备时,ping 工作正常。不知道问题出在哪里?是网络问题还是它的编码问题?

注意:我正在定期执行 ping,因为 on Disconnected Event is not working。我假设 ping 失败意味着设备已与应用程序断开连接。

【问题讨论】:

  • 您具体指的是哪种设备?显而易见的问题:当您无法 ping 时,您可以远程登录到设备吗?当我使用 uFace800 时,我遇到了一系列网络问题,这是在理想的网络条件下发生的吗?短电缆,良好的开关等。
  • 我还没有telnet设备,它是K20型号。

标签: c# connection biometrics zkteco zkemkeeper


【解决方案1】:

首先:感谢您阅读我的文章

你做错了。

无需每 25 秒 ping 一次设备。

UniversalStatic.PingTheDevice 方法的唯一工作是在您第一次连接设备时检查设备是否可能处于活动状态

如果要查看设备状态ieIsDeviceConnected,只需注册SDK提供的设备OnDisConnected事件即可。

第 57 行的 the code here 似乎已经为您完成了 OnDisConnected 事件注册。

当设备本身调用 ZkemClient.cs 类中的 objCZKEM_OnDisConnected 方法时,您现在需要做的就是将 IsDeviceConnected 设置为 false。

示例 sn-p: 在 ZkemClient.cs 类文件中,行号 81-84 之间

void objCZKEM_OnDisConnected()
{
     IsDeviceConnected = false;  // <-- Add this line
}

现在,每次您尝试调用设备时,您需要做的就是检查 IsDeviceConnected 的值。

【讨论】:

  • 感谢您的回复,但是当我关闭设备或拔下网络电缆时,OnDisconected 事件没有触发。我已经问过这个问题(3个月前)。 stackoverflow.com/questions/52090851/… 这就是我在 25 秒后 ping 设备以了解设备是否仍然连接的原因。
  • 您是否尝试过在 ZkemClient.cs 中调用 objCZKEM.Connect_Net 方法之前注册 OnDisConnected 事件。在某些设备中,第 57 行的代码需要放在 ZkemClient.cs 文件中的第 49 行之前。
  • 刚刚根据您的建议进行了测试 objCZKEM.OnDisConnected += objCZKEM_OnDisConnected; if (objCZKEM.Connect_Net(IPAdd, Port)) 但没有改变
  • 任何暗示我做错了什么?这项工作基于您的努力(正如我所提到的)。设备断开连接,我不知道原因,因此我发出 ping 请求。
  • 我不认为你做的事件注册部分是错误的。只是某些设备的行为不同。设备实际上进入睡眠模式。您可以尝试做的是在对设备进行任何其他调用(读/写操作)之前使用 EnableDevice 函数。 EnableDevice(machineNumber, false) 将设备设置为工作状态,EnableDevice(machineNumber, true) 将设备设置为非工作状态。您也可以尝试使用 DisableDeviceWithTimeOut 方法将超时设置长一点。
【解决方案2】:

没有实际的代码和硬件设置,这个答案有点摸不着头脑,但这里……

由于它最初可以工作,因此这不是硬件配置或网络配置问题。然而,它说在一段时间后目的地(阅读器)变得不可用。这可能不是网络保活问题,因为您每 25 秒 ping 一次。查看您引用的代码,它显示打开连接并连接回调,并调用硬件功能。

我的猜测可能是您在每次 ping 时都打开连接而不是关闭连接,然后在多次尝试后硬件卡住了,因为打开的连接太多。只是一个猜测。如果这是问题所在,那么要修复它,要么关闭连接,要么更好地保持连接打开并重新使用它。

另一种可能性是您的代码和设备之间的路由器检测到过多的 ping 并阻止连接作为可能的 DOS 攻击。如果这是问题,那么要解决它,将路由器配置为允许流量。

【讨论】:

  • 返回的错误必须处理网络堆栈无法将 IMCP 数据包发送到设备,因为没有人知道它是哪台机器(IE:它可能没有响应 ARP)。这应该消除连接数理论。此外,DDOS 保护不会每隔 25 秒触发一次。
【解决方案3】:

这听起来像是设备行为不端。错误“目标主机无法访问”对应于 ICMP 数据包,该数据包类型与 ping 相同,但工作不同,由您的路由器发送,说“我不知道哪个设备具有该 IP”。这通常发生在设备停止响应 ARP 时,它基本上会询问“谁有这个 IP?”并期望机器用其 MAC 地址响应“我拥有它”。路由器不断刷新其 ARP 表,忘记旧值。

因此,当您启动设备时,它是“快乐的”,响应 ARP 并响应 ping;但是,发生了一些事情,它至少停止响应 ARP(可能有更多问题)。根据其架构,它可能会被加载执行其他操作而无法响应,或者它可能只是被锁定。

尝试减慢对设备的其他操作(如果您轮询它以获取除 ping 以外的信息,请放慢速度),并查看您是否可以通过另一个输出从设备获取状态(它有 uart 吗?)。

【讨论】:

    【解决方案4】:

    选项 1

    由于重启设备会在一段时间内解决您的问题,因此请检查您正在使用的 IP 是否未在其他设备/计算机/element_of_the_network 上使用。

    ZKTeco 设备默认配置 IP 192.168.1.201。配置不同的静态 IP 并避免使用 DHCP(众所周知,在 ZKTeco 设备中使用 DHCP 不是一个好的选择,因为它们不会在重新启动系统或任何网络更改后自动刷新 IP )。

    确保该 IP 没有被使用,并且没有其他人会使用它。

    选项 2

    另一件事可能是您的问题的原因,是您在应用程序的不同部分(或不同的应用程序)中使用 zkemkeeper,并且您没有正确关闭打开的连接......这可能是阻止来自设备的所有网络活动。要关闭连接,请确保在执行所有必要操作后调用此 sdk 方法:

    sdk.Disconnect();
    

    【讨论】:

    • DHCP 是不错的选择。如果您在更改网络时重置设备或禁用/启用 DHCP,它将选择正确的。如果它没有选择一个,那么给定的 LAN 连接可能集成了两个网络,在这种情况下,设备将无法连接到互联网。所以它也有利于快速排除故障......
    • 一般 DHCP 是一个不错的选择,但在这种情况下,ZKTeco 设备不会在重启设备或任何网络更改后自动刷新 IP...您必须亲自前往设备并更新通过菜单禁用 dhcp 并再次启用它来手动进行。这就是为什么在这种情况下我不建议使用它。
    • 我使用的是静态 IP,没有使用 DHCP
    【解决方案5】:

    看起来像是代码问题。在调查UniversalStatic.PingTheDevice(ipAddress) 时,发现其调用 System.Net.NetworkInformation.Ping.Send 设置 DontFragment = true。参考:https://github.com/zaagan/BioMetrix/blob/master/BioMetrixCore/Utilities/UniversalStatic.cs#LC51。 ping 的超时设置为 120 毫秒。这会尝试向给定 IP 发送 32 字节的数据。

    以下是来自https://docs.microsoft.com/en-us/dotnet/api/system.net.networkinformation.ping.send?view=netframework-4.7.2 的 sn-p 将回答您问题的根本原因

    如果 DontFragment 属性为 true 并且数据包总大小超过本地和远程计算机之间的一个路由节点可以传输的最大数据包大小,则 ICMP 回显请求将失败。发生这种情况时,状态将设置为 PacketTooBig。

    因此,当您重新启动设备时,网络上传输的数据可能会丢失。因此它开始工作,直到数据包达到其限制。

    一些建议:

    • 在返回之前尝试在 PingTheDevice 中调用 System.Net.NetworkInformation.Ping.Dispose
    • 将超时时间从 120 毫秒增加到秒。
    • 将 timerCheckPingAndCloseAttendanceForm.Interval 增加到 1 分钟。
    • 查看System.Net.NetworkInformation.Ping.Send的返回码,找到相关的失败含义

    如果上述建议不能帮助您找到根本原因,请分享您的发现。

    【讨论】:

    • 实际上如果关闭检查 pindDevice 方法超时已经设置为 120。
    • 是的。我在回答中也提到了同样的事情。 timeout 是为了返回阻塞函数。它不一定会关闭参与的资源。如果函数完成是在之前,甚至在它达到超时持续时间之前,函数将被返回。因此,您可以将其保持在高位以允许 ping 完成其全部工作,以便您可以再次快速 ping。
    • 希望,提出上述建议和测试不会超过 15 分钟...。请确认建议是否有助于/没有帮助进行更改。否则,我们只能分享猜测。
    【解决方案6】:

    你试试这个代码来 ping 设备,

    try
            {
                IPAddress ipAddress = IPAddress.Parse(ipAdd);
    
                Ping pingSender = new Ping();
                PingOptions options = new PingOptions();
                options.DontFragment = true;
    
                // Create a buffer of 32 bytes of data to be transmitted. 
                string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
                byte[] buffer = Encoding.ASCII.GetBytes(data);
                int timeout = 120;
                PingReply reply = pingSender.Send(ipAddress, timeout, buffer, options);
    
                if (reply.Status == IPStatus.Success)
                    return true;
                else
                {
                    return false;
                }
            }
            catch (Exception)
            {
                return false;
            }
    

    谢谢。

    【讨论】:

      猜你喜欢
      • 2021-12-13
      • 1970-01-01
      • 2018-12-19
      • 1970-01-01
      • 2022-08-23
      • 1970-01-01
      • 2019-10-17
      • 2016-05-26
      • 2017-07-04
      相关资源
      最近更新 更多