J'ai le périphérique biométrique ZKTeco qui est connecté à une application Windows C # avec Ce tutoriel (Guide de démarrage du périphérique biométrique C # ZKTeco) .
Cela fonctionne bien, mais après un certain temps, mon application n'a pas réussi à envoyer une requête ping à l'appareil. Comme le code suggéré ci-dessous, j'essaie d'envoyer une requête ping à l'appareil toutes les 25 secondes.
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);
}
}
Et lorsque j'essaie de lancer un ping sur la commande de cmd, le périphérique affiche destination Host is unreachable
. Mais chaque fois que je redémarre le périphérique, la commande ping fonctionne bien. Je ne sais pas où est le problème? Le problème de réseau ou son problème de codage?
Remarque: Je fais un ping à intervalle régulier, car sur Disconnected Event ne fonctionne pas . Je suppose que la commande ping a échoué, ce qui signifie que le périphérique s'est déconnecté de l'application.
Tout d'abord: Merci d'avoir parcouru mon article
Vous le faites mal.
Il est inutile d'essayer de faire un ping sur le périphérique toutes les 25 secondes.
Le seul travail de la méthode UniversalStatic.PingTheDevice consiste à vérifier si le périphérique est probablement actif lors de la première connexion avec le périphérique.
Si vous souhaitez vérifier le statut du périphérique i.eIsDeviceConnected
, il vous suffit de vous inscrire à l'événement device OnDisConnected fourni par le SDK.
Il semble le code ici à la ligne 57 a déjà effectué l'enregistrement de l'événement OnDisConnected pour vous.
Il ne vous reste plus qu'à configurer votre IsDeviceConnected sur false lorsque la méthode objCZKEM_OnDisConnected de la classe ZkemClient.cs est appelée par le périphérique lui-même.
Exemple d’extrait de code: Dans le fichier de classe ZkemClient.cs, entre le numéro de ligne 81-84
void objCZKEM_OnDisConnected()
{
IsDeviceConnected = false; // <-- Add this line
}
Maintenant, chaque fois que vous essayez d'appeler le périphérique, il vous suffit de vérifier la valeur de votre IsDeviceConnected.
N'ayant pas le code et la configuration matérielle, cette réponse est un peu un coup dans le noir, mais voilà…
Comme cela fonctionne initialement, il ne s'agit pas d'un problème de configuration matérielle ou de configuration réseau. Pourtant, il est indiqué qu'après un certain temps, la destination (lecteur) devient indisponible. Ce n'est probablement pas un problème de maintenance réseau, car vous envoyez une requête ping toutes les 25 secondes. En regardant le code que vous avez référencé, il montre l’établissement d’une connexion, l’établissement de rappels et l’appel d’une fonctionnalité matérielle.
Mon hypothèse serait peut-être que vous ouvrez la connexion à chaque ping et que vous ne fermez pas la connexion, puis après un certain nombre de tentatives, le bourrage matériel s'est produit car il y a trop de connexions ouvertes. Juste une supposition. Si tel est le problème, corrigez-le, fermez la connexion ou, mieux, gardez la connexion ouverte et réutilisez-la.
Une autre possibilité serait que le (s) routeur (s) situé (s) entre votre code et le périphérique détecte trop de pings et bloque la connexion en tant qu’attaque DOS possible. Si tel est le problème, pour le résoudre, configurez le routeur pour autoriser le trafic.
Cela ressemble à l'appareil mal se comporter. L'erreur "L'hôte de destination est inaccessible" correspond à un paquet ICMP, le même type de paquet que le ping mais un travail différent, envoyé par votre routeur en disant "Je ne sais pas quel périphérique a cette adresse IP". Cela se produit normalement lorsque le périphérique cesse de répondre à ARP, qui demande en gros "qui a cette adresse IP?" et s'attend à ce qu'une machine réponde "je l'ai" avec son adresse MAC. Le routeur actualise constamment sa table ARP, en oubliant les anciennes valeurs.
Ainsi, lorsque vous démarrez le périphérique, il est «content» de répondre à ARP et aux pings. cependant, quelque chose se produit et au moins, il cesse de répondre à ARP (probablement quelque chose de plus faux avec cela). Selon son architecture, il pourrait être chargé d'effectuer d'autres tâches et ne pas pouvoir répondre, ou simplement être verrouillé.
Essayez de ralentir d'autres actions sur le périphérique (si vous l'interrogez pour obtenir des informations autres que le ping, rendez-vous plus lent) et voyez également si vous pouvez obtenir le statut du périphérique via une autre sortie (a-t-il un uart?).
OPTION 1
Étant donné que le redémarrage de l'appareil corrige votre problème pendant un certain temps, vérifiez que l'adresse IP que vous utilisez n'est pas utilisée sur un autre appareil/ordinateur/élément_du_réseau.
Les appareils ZKTeco sont livrés avec l'IP 192.168.1.201 configuré par défaut. Configurez une adresse IP statique différente et évitez d’utiliser DHCP (il est bien connu que l’utilisation de DHCP dans les périphériques ZKTeco n’est pas un bon choix car ils ne rafraîchissent pas automatiquement l’IP après le redémarrage du système ou tout changement de réseau).
Assurez-vous que l'adresse IP n'est pas utilisée et que personne d'autre ne l'utilisera.
OPTION 2
Une autre chose qui pourrait expliquer votre problème est que vous utilisez zkemkeeper dans une autre partie de votre application (ou dans une autre application) et que vous ne fermez pas correctement les connexions ouvertes ... Cela peut bloquer tout le réseau. activité de l'appareil. Pour fermer la connexion, assurez-vous d'appeler cette méthode sdk après avoir effectué toutes les actions nécessaires:
sdk.Disconnect();
Cela ressemble à un problème de code. Lors de son enquête sur UniversalStatic.PingTheDevice(ipAddress)
, il a constaté que l'appelant System.Net.NetworkInformation.Ping.Send donnait le paramètre DontFragment = true. Référence: https://github.com/zaagan/BioMetrix/blob/master/BioMetrixCore/Utilities/UniversalStatic.cs#LC51 . Le délai d'attente du ping est défini à 120 millisecondes. Cela tente d'envoyer 32 octets de données à l'IP donnée.
Voici l'extrait extrait de https://docs.Microsoft.com/en-us/dotnet/api/system.net.networkinformation.ping.send?view=netframework-4.7.2 répondrait à la racine cause de votre problème
Si la propriété DontFragment a la valeur true et que la taille de paquet totale dépasse la taille de paquet maximale pouvant être transmise par l'un des nœuds de routage entre les ordinateurs local et distant, la demande d'écho ICMP échoue. Lorsque cela se produit, le statut est défini sur PacketTooBig.
Ainsi, lorsque vous redémarrez votre appareil, les données qui transitent sur le réseau sont éventuellement perdues. Par conséquent, il a commencé à fonctionner jusqu'à ce que les paquets atteignent sa limite.
Quelques suggestions:
System.Net.NetworkInformation.Ping.Dispose
dans PingTheDevice avant de revenir.System.Net.NetworkInformation.Ping.Send
et recherchez le sens de l'échec associé.Veuillez partager vos conclusions si les suggestions ci-dessus ne vous aident pas à trouver la cause.