Я использую IcmpSendEcho
внутри своей программы, чтобы проверить, включен ли конкретный компьютер, соответствующий IP-адресу внутри моей внутренней сети.Это решение эффективно работает практически для всех наших клиентов, но у одного из них очень необычный случай.
Я, конечно, знаю, что это конкретный компьютер (кстати, бывает с несколькими компьютерами) включен и работает 24/7 , но поведение IcmpSendEcho
меняется в течение дня, и я не понимаю, почему.
Во время интервала с 05:00 до 20:00, IcmpSendEcho
на этом компьютере возвращает успешный эхо-запрос (IP_SUCCESS
) с вероятным временем приема-передачи, но в течение временного интервала с 08:00 до 05:00 IcmpSendEcho возвращает ошибку IP_DEST_HOST_UNREACHABLE
.Странная часть этого заключается в том, что время приема-передачи НЕ соответствует времени ожидания, назначенному функции IcmpSendEcho, но меньше.
Если я выполняю тест на компьютере, который переключаетсявыключен, мой код сообщает мне, что запрос IcmpSendEcho
не выполнен, поэтому код переходит в другой блок инструкций.
Почему это происходит?В чем разница между запросом IcmpSendEcho
, который не выполняется и выполняется, но с кодом ошибки, например IP_DEST_HOST_UNREACHABLE
?
Спасибо за вашу помощь.
unsigned long ipaddr = inet_addr(CT2CA(myIpAddress));
HANDLE hIcmpFile;
hIcmpFile = IcmpCreateFile();
if (hIcmpFile == INVALID_HANDLE_VALUE) {
printf("\tUnable to open handle.\n");
printf("IcmpCreatefile returned error: %ld\n", GetLastError());
EDMLog::Error(_T("Unable to open handle. error code 001"));
errorCode = _T("001");
}
else {
char SendData[100];
for (int x = 0; x < 100; ++x) {
SendData[x] = 'A';
}
LPVOID ReplyBuffer = NULL;
DWORD ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
ReplyBuffer = (VOID*)malloc(ReplySize);
if (ReplyBuffer == NULL) {
printf("\tUnable to allocate memory\n");
EDMLog::Error(_T("Unable to allocate memory. error code 001"));
errorCode = _T("001");
}
else {
DWORD dwRetVal = IcmpSendEcho(hIcmpFile, ipaddr, SendData, sizeof(SendData),
NULL, ReplyBuffer, ReplySize, 10000);
printf("\tSent icmp message to %s\n", CT2CA(myIpAddress);
EDMLog::Information(_T("Test su indirizzo ") + myIpAddress);
if (dwRetVal != 0) {
/////////////////////////////////////
//HERE THE REQUEST IS SUCCESSFULL BUT THE ERROR CODE IS IP_DEST_HOST_UNREACHABLE
/////////////////////////////////////
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
struct in_addr ReplyAddr;
ReplyAddr.S_un.S_addr = pEchoReply->Address;
if (dwRetVal > 1) {
printf("\tReceived %ld icmp message responses\n", dwRetVal);
printf("\tInformation from the first response:\n");
}
else {
printf("\tReceived %ld icmp message response\n", dwRetVal);
printf("\tInformation from this response:\n");
}
printf("\t Received from %s\n", inet_ntoa(ReplyAddr));
printf("\t Status = %ld\n",
pEchoReply->Status);
switch (pEchoReply->Status) {
case IP_SUCCESS:
//GESTIONE PARTICOLARE PER GAROM
//errorCode.Format(_T("90%d"), i + 1);
//GESTIONE TRADIZIONALE
errorCode = _T("000");
EDMLog::Debug(_T("Test eseguito correttamente."));
break;
case IP_BUF_TOO_SMALL:
EDMLog::Error(_T("Buffer too small. error code 101"));
errorCode = _T("101");
break;
case IP_DEST_NET_UNREACHABLE:
EDMLog::Error(_T("DEST NET UNREACHABLE. error code 102"));
errorCode = _T("102");
break;
case IP_DEST_HOST_UNREACHABLE:
EDMLog::Error(_T("DEST HOST UNREACHABLE. error code 103"));
errorCode = _T("103");
break;
case IP_DEST_PROT_UNREACHABLE:
EDMLog::Error(_T("DEST PROT UNREACHABLE. error code 104"));
errorCode = _T("104");
break;
case IP_DEST_PORT_UNREACHABLE:
EDMLog::Error(_T("DEST PORT UNREACHABLE. error code 105"));
errorCode = _T("105");
break;
case IP_NO_RESOURCES:
EDMLog::Error(_T("IP NO RESOURCES. error code 106"));
errorCode = _T("106");
break;
case IP_BAD_OPTION:
EDMLog::Error(_T("IP BAD OPTION. error code 107"));
errorCode = _T("107");
break;
case IP_HW_ERROR:
EDMLog::Error(_T("IP HW ERROR. error code 108"));
errorCode = _T("108");
break;
case IP_PACKET_TOO_BIG:
EDMLog::Error(_T("IP PACKET TOO BIG. error code 109"));
errorCode = _T("109");
break;
case IP_REQ_TIMED_OUT:
EDMLog::Error(_T("IP REQ TIMED OUT. error code 110"));
errorCode = _T("110");
break;
case IP_BAD_REQ:
EDMLog::Error(_T("IP BAD REQ. error code 111"));
errorCode = _T("111");
break;
case IP_BAD_ROUTE:
EDMLog::Error(_T("IP BAD ROUTE. error code 112"));
errorCode = _T("112");
break;
case IP_TTL_EXPIRED_TRANSIT:
EDMLog::Error(_T("IP TTL EXPIRED TRANSIT. error code 113"));
errorCode = _T("113");
break;
case IP_TTL_EXPIRED_REASSEM:
EDMLog::Error(_T("IP TTL EXPIRED REASSEM. error code 114"));
errorCode = _T("114");
break;
case IP_PARAM_PROBLEM:
EDMLog::Error(_T("IP PARAM PROBLEM. error code 115"));
errorCode = _T("115");
break;
case IP_SOURCE_QUENCH:
EDMLog::Error(_T("IP SOURCE QUENCH. error code 116"));
errorCode = _T("116");
break;
case IP_OPTION_TOO_BIG:
EDMLog::Error(_T("IP OPTION TOO BIG. error code 117"));
errorCode = _T("117");
break;
case IP_BAD_DESTINATION:
EDMLog::Error(_T("IP BAD DESTINATION. error code 118"));
errorCode = _T("118");
break;
case IP_GENERAL_FAILURE:
EDMLog::Error(_T("IP GENERAL FAILURE. error code 150"));
errorCode = _T("150");
break;
}
printf("\t Roundtrip time = %ld milliseconds\n",
pEchoReply->RoundTripTime);
if ((int)(pEchoReply->RoundTripTime) == 0)
valore.Format(_T("%d"), 1);
else
valore.Format(_T("%d"),(int)(pEchoReply->RoundTripTime));
}
else {
/////////////////////////////////////
//HERE THE REQUEST IS NOT SUCCESSFUL (TIMEOUT)
/////////////////////////////////////
printf("\tCall to IcmpSendEcho failed.\n");
DWORD lastError = GetLastError();
printf("\tIcmpSendEcho returned error: %ld\n", lastError);
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
struct in_addr ReplyAddr;
ReplyAddr.S_un.S_addr = pEchoReply->Address;
if (dwRetVal > 1) {
printf("\tReceived %ld icmp message responses\n", dwRetVal);
printf("\tInformation from the first response:\n");
}
else {
printf("\tReceived %ld icmp message response\n", dwRetVal);
printf("\tInformation from this response:\n");
}
printf("\t Received from %s\n", inet_ntoa(ReplyAddr));
printf("\t Status = %ld\n",
pEchoReply->Status);
valore = _T("0");
switch (pEchoReply->Status) {
case IP_SUCCESS:
errorCode = _T("000");
EDMLog::Information(_T("Test eseguito correttamente."));
break;
case IP_BUF_TOO_SMALL:
EDMLog::Error(_T("Buffer too small. error code 101"));
errorCode = _T("101");
break;
case IP_DEST_NET_UNREACHABLE:
EDMLog::Error(_T("DEST NET UNREACHABLE. error code 102"));
errorCode = _T("102");
break;
case IP_DEST_HOST_UNREACHABLE:
EDMLog::Error(_T("DEST HOST UNREACHABLE. error code 103"));
errorCode = _T("103");
break;
case IP_DEST_PROT_UNREACHABLE:
EDMLog::Error(_T("DEST PROT UNREACHABLE. error code 104"));
errorCode = _T("104");
break;
case IP_DEST_PORT_UNREACHABLE:
EDMLog::Error(_T("DEST PORT UNREACHABLE. error code 105"));
errorCode = _T("105");
break;
case IP_NO_RESOURCES:
EDMLog::Error(_T("IP NO RESOURCES. error code 106"));
errorCode = _T("106");
break;
case IP_BAD_OPTION:
EDMLog::Error(_T("IP BAD OPTION. error code 107"));
errorCode = _T("107");
break;
case IP_HW_ERROR:
EDMLog::Error(_T("IP HW ERROR. error code 108"));
errorCode = _T("108");
break;
case IP_PACKET_TOO_BIG:
EDMLog::Error(_T("IP PACKET TOO BIG. error code 109"));
errorCode = _T("109");
break;
case IP_REQ_TIMED_OUT:
EDMLog::Error(_T("IP REQ TIMED OUT. error code 110"));
errorCode = _T("004");
valore = _T("10000");
break;
case IP_BAD_REQ:
EDMLog::Error(_T("IP BAD REQ. error code 111"));
errorCode = _T("111");
break;
case IP_BAD_ROUTE:
EDMLog::Error(_T("IP BAD ROUTE. error code 112"));
errorCode = _T("112");
break;
case IP_TTL_EXPIRED_TRANSIT:
EDMLog::Error(_T("IP TTL EXPIRED TRANSIT. error code 113"));
errorCode = _T("113");
break;
case IP_TTL_EXPIRED_REASSEM:
EDMLog::Error(_T("IP TTL EXPIRED REASSEM. error code 114"));
errorCode = _T("114");
break;
case IP_PARAM_PROBLEM:
EDMLog::Error(_T("IP PARAM PROBLEM. error code 115"));
errorCode = _T("115");
break;
case IP_SOURCE_QUENCH:
EDMLog::Error(_T("IP SOURCE QUENCH. error code 116"));
errorCode = _T("116");
break;
case IP_OPTION_TOO_BIG:
EDMLog::Error(_T("IP OPTION TOO BIG. error code 117"));
errorCode = _T("117");
break;
case IP_BAD_DESTINATION:
EDMLog::Error(_T("IP BAD DESTINATION. error code 118"));
errorCode = _T("118");
break;
case IP_GENERAL_FAILURE:
EDMLog::Error(_T("IP GENERAL FAILURE. error code 150"));
errorCode = _T("150");
break;
}
}
IcmpCloseHandle(hIcmpFile);
}
}
Очевидно, что любое улучшениеПриведенный выше код хорошо принят, еще раз спасибо.