7

我有ZKTeco Biometrics 设备,它使用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 操作,因为Disconnected Event is not working。我假设 ping 失败意味着设备已与应用程序断开连接。

4

6 回答 6

2

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

你做错了。

每 25 秒后尝试 ping 设备是不必要的。

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

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

似乎第 57 行的代码已经为您完成了OnDisConnected事件注册。

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

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

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

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

于 2018-12-07T10:15:29.820 回答
0

选项1

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

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

确保 IP 未在使用中,并且没有其他人会使用它。

选项 2

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

sdk.Disconnect();
于 2018-12-04T11:00:10.887 回答
0

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

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

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

于 2018-12-03T14:36:06.550 回答
0

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

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

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

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

几点建议:

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

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

于 2018-12-05T17:38:15.893 回答
0

您尝试使用此代码 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;
        }

谢谢。

于 2020-06-19T05:33:29.083 回答
0

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

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

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

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

于 2018-12-03T11:40:28.080 回答