Пинг биометрического устройства через некоторое время становится неэффективным
У меня есть устройство ZKTeco Biometrics, которое я подключил к приложению C# windows, используя данное руководство (C# ZKTeco Biometric Device Getting Started).
Он работает нормально, но через некоторое время моему приложению не удалось пропинговать устройство. Как показано в приведенном ниже коде, я пытаюсь пропинговать устройство каждые 25 секунд.
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, устройство показывает destination host is unreachable
, Но всякий раз, когда я перезагружаю устройство, пинг работает нормально. Я не знаю, где проблема? Проблема с сетью или проблема с ее кодированием?
0 ответов
Прежде всего: спасибо за просмотр моей статьи
Вы делаете это неправильно.
Попытка пинговать устройство через каждые 25 секунд не требуется.
Единственная задача метода UniversalStatic.PingTheDevice - проверить, является ли устройство предположительно активным, при первом подключении к устройству.
Если вы хотите проверить состояние устройства, т.е. IsDeviceConnected
Все, что вам нужно сделать, это зарегистрироваться на событие OnDisConnected устройства, предоставленное SDK.
Кажется, код здесь в строке номер 57 уже выполнил регистрацию события OnDisConnected для вас.
Все, что вам нужно сделать сейчас, это установить для IsDeviceConnected значение false, когда метод objCZKEM_OnDisConnected в классе ZkemClient.cs вызывается самим устройством.
Пример фрагмента: в файле класса ZkemClient.cs, между строкой 81-84
void objCZKEM_OnDisConnected()
{
IsDeviceConnected = false; // <-- Add this line
}
Теперь, каждый раз, когда вы пытаетесь позвонить на устройство, все, что вам нужно сделать, это проверить значение вашего IsDeviceConnected.
ОПЦИЯ 1
Поскольку перезапуск устройства устраняет вашу проблему на некоторое время, убедитесь, что используемый вами IP-адрес не используется на другом устройстве /computer/element_of_the_network.
Устройства ZKTeco поставляются с IP-адресом 192.168.1.201, настроенным по умолчанию. Настройте другой статический IP-адрес и избегайте использования DHCP (хорошо известно, что использование DHCP в устройствах ZKTeco не является хорошим выбором, поскольку они не обновляют автоматически IP-адрес после перезагрузки системы или любого изменения сети).
Убедитесь, что IP-адрес не используется и никто другой не будет его использовать.
ВАРИАНТ 2
Другая причина, по которой это может быть причиной вашей проблемы, заключается в том, что вы используете zkemkeeper в другой части вашего приложения (или в другом приложении), и вы не закрываете противоположные соединения должным образом... Это может блокировать всю сеть. активность с устройства. Чтобы закрыть соединение, просто убедитесь, что вы вызываете этот метод SDK после выполнения всех необходимых действий:
sdk.Disconnect();
Вы пробуете этот код для проверки связи с устройством,
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;
}
Спасибо.
Это похоже на проблему с кодом. Во время расследования UniversalStatic.PingTheDevice(ipAddress)
, он обнаружил, что он вызывает System.Net.NetworkInformation.Ping.Send параметр DontFragment = true. Ссылка: https://github.com/zaagan/BioMetrix/blob/master/BioMetrixCore/Utilities/UniversalStatic.cs#LC51. Время ожидания для пинга установлено в 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
и найти связанный смысл неудачи
Пожалуйста, поделитесь своими выводами, если приведенные выше предложения не помогут вам найти основную причину.
Это похоже на неправильное поведение устройства. Ошибка "узел назначения недоступен" соответствует пакету ICMP, пакету того же типа, что и ping, но другой работе, отправляемому вашим маршрутизатором с сообщением "Я понятия не имею, какое устройство имеет этот IP". Это обычно происходит, когда устройство перестает отвечать на ARP, который в основном спрашивает, "у кого есть этот IP?" и ожидает, что машина ответит "у меня есть" своим MAC-адресом. Маршрутизатор постоянно обновляет свою таблицу ARP, забывая старые значения.
Поэтому, когда вы загружаете устройство, оно "счастливое", отвечает на ARP и отвечает на пинги; однако, что-то происходит, и это по крайней мере перестает отвечать на ARP (вероятно, что-то более неправильное с этим). В зависимости от его архитектуры он может быть загружен, делая другие вещи и не может ответить, или он может быть просто заблокирован.
Попробуйте замедлить другие действия на устройстве (если вы запрашиваете информацию, отличную от ping, делайте это медленнее), а также посмотрите, сможете ли вы получить статус с устройства через другой выход (у него есть uart?).
Не имея фактического кода и аппаратной настройки, этот ответ немного в темноте, но здесь идет...
Поскольку он работает изначально, это не проблема аппаратной конфигурации или конфигурации сети. Тем не менее он говорит, что через некоторое время пункт назначения (читатель) становится недоступным. Вероятно, это не проблема поддержки активности сети, потому что вы пингуетесь каждые 25 секунд. Глядя на код, на который вы ссылались, он показывает, как открыть соединение и подключить обратные вызовы, а также сделать вызов аппаратной функции.
Я думаю, может быть, вы открываете соединение каждый пинг, а не закрываете соединение, а затем, после нескольких попыток, происходит зависание оборудования из-за слишком большого количества открытых соединений. Просто предположение. Если это проблема, то для ее устранения либо закройте соединение, либо, лучше, оставьте соединение открытым и используйте его повторно.
Альтернативной возможностью может быть то, что маршрутизатор (ы) между вашим кодом и устройством обнаруживает слишком много пингов и блокирует соединение как возможную атаку DOS. Если это проблема, то для ее устранения настройте маршрутизатор, чтобы разрешить трафик.