Funkcja do sprawdzania pingu ścina program – czym jest to spowodowane?

0

Witam,
Znalazłem na internecie taka funkcje do do sprawdzania pingu na danym serwerze, działa prawidłowo lecz lekko scina mój program za każdym razem gdy wywołuje się ta funkcja, czym to może być spowodowane?

int Game::getNewPing(const std::string& ip)
{
	HANDLE hIcmpFile;
	unsigned long ipaddr = inet_addr(ip.c_str());
	DWORD dwRetVal = 0;
	char SendData[32] = "Data Buffer";
	LPVOID ReplyBuffer = NULL;
	DWORD ReplySize = 0;

	// Validate the parameters

	if (ipaddr == INADDR_NONE) {
		return 0;
	}

	hIcmpFile = IcmpCreateFile();
	if (hIcmpFile == INVALID_HANDLE_VALUE) {
		g_logger.info(stdext::format("\tUnable to open handle.\n"));
		g_logger.info(stdext::format("IcmpCreatefile returned error: %ld\n", GetLastError()));
		return 0;
	}

	ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
	ReplyBuffer = (VOID*)malloc(ReplySize);
	if (ReplyBuffer == NULL) {
		g_logger.info(stdext::format("\tUnable to allocate memory\n"));
		return 0;
	}


	dwRetVal = IcmpSendEcho(hIcmpFile, ipaddr, SendData, sizeof(SendData),
		NULL, ReplyBuffer, ReplySize, 5000);
	if (dwRetVal != 0) {
		PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
		struct in_addr ReplyAddr;
		ReplyAddr.S_un.S_addr = pEchoReply->Address;
		return pEchoReply->RoundTripTime;
	}
	else {
		g_logger.info(stdext::format("\tCall to IcmpSendEcho failed.\n"));
		g_logger.info(stdext::format("\tIcmpSendEcho returned error: %ld\n", GetLastError()));
		return 0;
	}
	return 0;
}
1

Może to być spowodowane tym, że nie zwalniasz zaalokowanej pamięci

ReplyBuffer = (VOID*)malloc(ReplySize);
2

Funkcja IcmpSendEcho jest blokująca - czeka na odpowiedź.

0
PanRiK napisał(a):

Może to być spowodowane tym, że nie zwalniasz zaalokowanej pamięci

ReplyBuffer = (VOID*)malloc(ReplySize);

Probowałem z free(ReplyBuffer); ale nie pomaga.

Azarien napisał(a):

Funkcja IcmpSendEcho jest blokująca - czeka na odpowiedź.

Można więc jakoś ją zastąpić?

0
Azarien napisał(a):

Funkcja IcmpSendEcho jest blokująca - czeka na odpowiedź.

Można więc jakoś ją zastąpić?

https://docs.microsoft.com/en-us/windows/desktop/api/icmpapi/nf-icmpapi-icmpsendecho

Jest tam jakieś IcmpSendEcho2 i IcmpSendEcho2Ex które pozwalają na wywołanie asynchroniczne, możesz też zrobić to w osobnym wątku.

0
Azarien napisał(a):

Funkcja IcmpSendEcho jest blokująca - czeka na odpowiedź.

dwRetVal = IcmpSendEcho2(hIcmpFile, NULL, NULL, NULL, ipaddr, SendData, sizeof(SendData), NULL, ReplyBuffer, ReplySize, 5000);

Także laguje, przetestuje teraz IcmpSendEcho2Ex i dam znać.

0

Z dokumentacji, do której linka wskazał @Azarien masz:

"The IcmpSendEcho2 function sends an IPv4 ICMP echo request and returns either immediately (if Event or ApcRoutine is non-NULL)"

W Twoim przypadku obydwa są NULL, więc wpadasz w drugą część

"or returns after the specified time-out. The ReplyBuffer contains the ICMP echo responses, if any."

Timeout ustawiłeś na 5000 milisekund, więc laguje Ci te 5 sekund...

0

Nie wystarczy dodać 2 do nazwy funkcji, trzeba przeczytać opis. Tak jak masz to musi ci lagować, bo operacja pinga swoje po prostu trwa - zresztą na pomiarze tego czasu właśnie ci zależy.

0
yarel napisał(a):
ruth napisał(a):
Azarien napisał(a):

Funkcja IcmpSendEcho jest blokująca - czeka na odpowiedź.

dwRetVal = IcmpSendEcho2(hIcmpFile, NULL, NULL, NULL, ipaddr, SendData, sizeof(SendData), NULL, ReplyBuffer, ReplySize, 5000);

Także laguje, przetestuje teraz IcmpSendEcho2Ex i dam znać.

Z dokumentacji, do której linka wskazał @Azarien masz:

"The IcmpSendEcho2 function sends an IPv4 ICMP echo request and returns either immediately (if Event or ApcRoutine is non-NULL)"

W Twoim przypadku obydwa są NULL, więc wpadasz w drugą część

"or returns after the specified time-out. The ReplyBuffer contains the ICMP echo responses, if any."

Timeout ustawiłeś na 5000 milisekund, więc laguje Ci te 5 sekund...

Ten lag trwa tyle jakies milisekundy obstawiam że czas przychodzacego pingu, a nie 5 sekund ostatni parametr nie ma nic do rzeczy probowalem z 100, 1000, 5000 ciagle tak samo.

Azarien napisał(a):

Nie wystarczy dodać 2 do nazwy funkcji, trzeba przeczytać opis. Tak jak masz to musi ci lagować, bo operacja pinga swoje po prostu trwa - zresztą na pomiarze tego czasu właśnie ci zależy.

Nie chodzi tu czasem o 3 i 4 parametr w którym ja mam NULL?

0

Dowiedziałem się ze trzeba wywołać ta funkcje asynchronicznie ale na tym poradniku https://docs.microsoft.com/en-us/windows/desktop/api/icmpapi/nf-icmpapi-icmpsendecho2
nie pisze jak to zrobić.

0
ruth napisał(a):

...

Ten lag trwa tyle jakies milisekundy obstawiam że czas przychodzacego pingu, a nie 5 sekund ostatni parametr nie ma nic do rzeczy probowalem z 100, 1000, 5000 ciagle tak samo.

Tak, masz rację. 5 sek to timeout, czyli max. czas oczekiwania na odpowiedź.

Nie chodzi tu czasem o 3 i 4 parametr w którym ja mam NULL?

Sygnatura funkcji jest następująca:

DWORD IcmpSendEcho2(
  HANDLE                 IcmpHandle,
  HANDLE                 Event,
  PIO_APC_ROUTINE        ApcRoutine,
  PVOID                  ApcContext,
  IPAddr                 DestinationAddress,
  LPVOID                 RequestData,
  WORD                   RequestSize,
  PIP_OPTION_INFORMATION RequestOptions,
  LPVOID                 ReplyBuffer,
  DWORD                  ReplySize,
  DWORD                  Timeout
);

Parametr 3 to funkcja, która zostanie wywołana, gdy przyjdzie odpowiedź na pinga (taki "callback").

Parametr 4 to takie dodatkowe info, które ma być przekazane do ApcRouting, czyli coś co pozwoli Ci określić czego dotyczy odpowiedź (kontekst w jakim wołany jest callback). Możesz tam przekazać jakieś requestId, timestamp, correlationid, pid, uchwyt okienka, etc. (co tam sobie wymyślisz, że jest Ci potrzebne do wykonania reakcji na odpowiedź na pinga).

0

Chyba trzeba jakoś zdefiniowac 2 parametr event, szukalem na necie jak to zrobic ale nie znalazłem.

0

Czytałem, próbowałem kompilować w rożnych mozliwosciach i nic z tego. Mam nadzieje ze podsuniecie jakiś przykład ja się poddaje.
Dodam ze w moich bibliotekach ta funkcja tak wygdląda, jak dodaje PIO_APC_ROUTINE_DEFINED do definicji to bład jest.

IcmpSendEcho2(
    _In_                        HANDLE                   IcmpHandle,
    _In_opt_                    HANDLE                   Event,
#ifdef PIO_APC_ROUTINE_DEFINED
    _In_opt_                    PIO_APC_ROUTINE          ApcRoutine,
#else
    _In_opt_                    FARPROC                  ApcRoutine,
#endif
    _In_opt_                    PVOID                    ApcContext,
    _In_                        IPAddr                   DestinationAddress,
    _In_reads_bytes_(RequestSize)    LPVOID                   RequestData,
    _In_                        WORD                     RequestSize,
    _In_opt_                    PIP_OPTION_INFORMATION   RequestOptions,
    _Out_writes_bytes_(ReplySize)     LPVOID                   ReplyBuffer,
    _In_range_(>=, sizeof(ICMP_ECHO_REPLY) + RequestSize + 8)
    DWORD                    ReplySize,
    _In_                        DWORD                    Timeout
    );
0
ruth napisał(a):

Czytałem, próbowałem kompilować w rożnych mozliwosciach i nic z tego. Mam nadzieje ze podsuniecie jakiś przykład ja się poddaje.

https://stackoverflow.com/questions/16352158/how-to-implement-icmpsendecho2-asynchronous-with-callback-example-vc

edited:
Dziwi mnie to poddawanie się w czasach internetu. Kiedyś były specyfikacje, dokumentacja w plikach tekstowych i ludzie dawali radę, próbując, notując porażką za porażką i czegoś się ucząc;-) Dziś mogę polecić zapytania w google typu: "site:github.com IcmpSendEcho2"

0

Probowałem tego. Jak dodaje (FARPROC)ReplyCame to jest crash.

0

Nie crashuje ale nie działa tez asynchronicznie czyli lag jest.

1 użytkowników online, w tym zalogowanych: 0, gości: 1