IcmpSendEcho returns 183
IcmpSendEcho returns 183
本文关键字:returns IcmpSendEcho 更新时间:2023-10-16
我在这里改编了MSDN中的这个代码示例。如果我单独构建它,它可以很好地工作,但如果我将它添加到应用程序中,它就会失败。为了方便起见,我包括了对我所学课程的精确改编。
我只想每秒钟做一次简单的ping。如果没有管理权限,原始套接字就无法工作,而且这种ICMP.dll方法在我的应用程序中也无法工作,我不明白为什么。错误183的行是"无法创建文件,因为它已经存在",这在上下文中毫无意义。
有人能发现问题吗?非常感谢你的帮助。
Ping.h
#pragma once
#include "Ping.h"
#include "LogBase.h"
class WinPing :
public Ping
{
public:
WinPing(char* address, int period);
~WinPing();
unsigned long GetRTT();
private:
HANDLE _hIcmpFile;
unsigned long _ipaddr;
DWORD _dwRetVal;
LPVOID _replyBuffer;
DWORD _replySize;
static HANDLE _inputTimer;
int _period;
unsigned long _lastRTT;
static DWORD WINAPI AsyncPingHandler(void* Param);
void DoPing();
};
WinPing.h
#pragma once
#include "Ping.h"
#include "LogBase.h"
class WinPing :
public Ping
{
public:
WinPing(char* address, int period);
~WinPing();
unsigned long GetRTT();
private:
HANDLE _hIcmpFile;
unsigned long _ipaddr;
DWORD _dwRetVal;
LPVOID _replyBuffer;
DWORD _replySize;
static HANDLE _inputTimer;
int _period;
unsigned long _lastRTT;
static DWORD WINAPI AsyncPingHandler(void* Param);
void DoPing();
};
WinPing.cpp
#include "WinPing.h"
#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>
#include <stdio.h>
#include "utils.h"
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
HANDLE WinPing::_inputTimer = NULL;
char SendData[32] = "Data Buffer";
unsigned long WinPing::GetRTT()
{
return _lastRTT;
}
void WinPing::DoPing()
{
LARGE_INTEGER t;
t.HighPart = t.LowPart = 0;
SetWaitableTimer(_inputTimer, &t, _period, NULL, NULL, TRUE);
while (true)
{
int r = WaitForSingleObject(_inputTimer, _period * 2);
if (r != WAIT_OBJECT_0)
{
LogLog("InputHandler: Bad Timer return", LogError);
}
_dwRetVal = IcmpSendEcho(_hIcmpFile, _ipaddr, SendData, sizeof(SendData),
NULL, _replyBuffer, _replySize, 1000);
if (_dwRetVal != 0) {
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)_replyBuffer;
struct in_addr ReplyAddr;
ReplyAddr.S_un.S_addr = pEchoReply->Address;
LogLog("tSent icmp message to %sn", LogDebug, _address);
if (_dwRetVal > 1) {
LogLog("tReceived %ld icmp message responsesn", LogDebug, _dwRetVal);
LogLog("tInformation from the first response:n", LogDebug);
}
else {
LogLog("tReceived %ld icmp message responsen", LogDebug, _dwRetVal);
LogLog("tInformation from this response:n", LogDebug);
}
LogLog("t Received from %sn", LogDebug, inet_ntoa(ReplyAddr));
LogLog("t Status = %ldn", LogDebug,
pEchoReply->Status);
LogLog("t Roundtrip time = %ld millisecondsn", LogDebug,
pEchoReply->RoundTripTime);
//needs synchronization here. Probably not very important
_lastRTT = pEchoReply->RoundTripTime;
LogLog("t Roundtrip time = %ld millisecondsn", LogDebug, _lastRTT);
IcmpCloseHandle(_hIcmpFile);
}
else {
LogLog("tCall to IcmpSendEcho failed.n", LogError);
LogLog("tIcmpSendEcho returned error: %ldn", LogError, GetLastError());
}
}
}
DWORD WINAPI WinPing::AsyncPingHandler(void* Param)
{
_inputTimer = CreateWaitableTimer(NULL, false, NULL);
if (!_inputTimer)
{
LogLog("Unable to create input waitable timer", LogError);
return 1;
}
LogLog("RTT Ping Thread started", LogDebug);
WinPing* This = (WinPing*)Param;
This->DoPing();
return 0;
}
WinPing::WinPing(char* address, int period)
:Ping(address),
_period(period)
{
// Declare and initialize variables
_ipaddr = INADDR_NONE;
_dwRetVal = 0;
_replyBuffer = NULL;
_replySize = 0;
_ipaddr = inet_addr(address);
if (_ipaddr == INADDR_NONE) {
LogLog("Not an IP Address:%s", LogError, address);
return;
}
_hIcmpFile = IcmpCreateFile();
if (_hIcmpFile == INVALID_HANDLE_VALUE) {
LogLog("tUnable to open handle.n", LogError);
LogLog("IcmpCreatefile returned error: %ldn", LogError, GetLastError());
return;
}
_replySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
_replyBuffer = (VOID*)malloc(_replySize);
if (_replyBuffer == NULL) {
LogLog("tUnable to allocate memoryn", LogError);
return;
}
//Spawn thread on AsyncPingHandler()
CreateClassThread(AsyncPingHandler, this);
}
WinPing::~WinPing()
{
}
在IcmpSendEcho()
失败后,您不会立即调用GetLastError()
(与调用IcmpCreateFile()
时相同)。您首先调用LogLog()
,这可能会更改GetLastError()
返回的错误代码,例如,如果它正在记录到找不到的文件ALWAYS在执行任何可能调用系统函数的操作之前调用GetLastError()
。
else {
DWORD dwErrCode = GetLastError(); // <-- call GetLastError() first
LogLog("tCall to IcmpSendEcho failed.n", LogError);
LogLog("tIcmpSendEcho returned error: %un", LogError, dwErrCode); // <-- then use the value when needed
return;
}
我发现一种更简单、更稳定的ping方法是使用GetRTTandHopCount。下面是一个例子。
UINT ip = inet_addr(serverAddress);
ULONG hopCount = 0;
ULONG RTT = 0;
if (GetRTTAndHopCount(ip, &hopCount, 30, &RTT) == TRUE) {
printf("Hops: %ldn", hopCount);
printf("RTT: %ldn", RTT);
}
else {
printf("Error: %ldn", GetLastError());
}
return RTT;
相关文章:
- CreateWICTextureFromFile returns E_NOINTERFACE
- cl::Event::waitForEvents returns -7 (CL_EXEC_STATUS_ERROR_ F
- WinAPI IcmpSendEcho on 64-bit platform
- vector[0].getPosition() returns 0
- CreateInputLayout returns E_INVALIDARG
- ldap_search_s returns LDAP_OPERATIONS_ERROR
- CreateCompatibleDC(IntPtr.Zero) returns IntPtr.Zero
- glUniformLocation returns -1
- DirectX9 CreateOffscreenPlainSurface returns D3DERR_INVALIDC
- OpenGL glReadPixels returns 0
- gdk_screen_get_default() returns null
- UIAutomation: AddAutomationEventHandler() returns E_INVALIDA
- C++ _snprintf returns -1
- CryptHashData returns ERROR_INVALID_PARAMETER (CAPI)
- FindClass returns null
- QEnableSharedFromThis::sharedFromThis() returns nullptr
- SDL_ttf TTF_OpenFont returns NULL
- MFC C++:IcmpSendEcho 成功返回,但状态为 IP_DEST_HOST_UNREACHABLE,并且 R
- QSslSocket and supportsSsl() returns false
- IcmpSendEcho returns 183