|
I'm aware of these bugs, I'll get round to updating this article soon.
|
|
|
|
|
Thank you! But so sorry for the late reply!
I also realized this problem from Microsoft code sample, so, I
had found an other way to solve this problem - using MS ICMP APIs. Here is my code:
#define PING_WINSOCK_VERSION 0x0101
#define PING_REQ_DATASIZE 64 // Echo Request Data size
#define PING_ERROR_SUCCESS 0
#define PING_ERROR_TIMEOUT 1
#define PING_ERROR_SOCKET 2
typedef struct tagIPINFO
{
unsigned char Ttl; // Time To Live
unsigned char Tos; // Type Of Service
unsigned char IPFlags; // IP flags
unsigned char OptSize; // Size of options data
unsigned char far * Options; // Options data buffer
}IPINFO, *PIPINFO;
typedef struct tagICMPECHO
{
unsigned long Source; // Source address
unsigned long Status; // IP status
unsigned long RTTime; // Round trip time in milliseconds
unsigned short DataSize; // Reply data size
unsigned short Reserved; // Unknown
void far * pData; // Reply data buffer
IPINFO ipInfo; // Reply options
}ICMPECHO, * PICMPECHO;
// Ping results
typedef struct tagPINGINFO
{
char cHostName[32];
char cIpAddress[20];
char cErrorMessage[256];
unsigned int blTimouted;
short nSendBytes;
short nReplyBytes;
unsigned long nReplyTime;
unsigned char nReplyTTL;
}PINGINFO, *PPINGINFO;
__declspec(dllexport) unsigned int _cdecl PingHost( void far* lpPingInfo )
{
PPINGINFO pPingInfo = (PPINGINFO)lpPingInfo;
if(pPingInfo == NULL)return( FALSE );
HANDLE (WINAPI *pIcmpCreateFile)(VOID);
BOOL (WINAPI *pIcmpCloseHandle)(HANDLE);
DWORD (WINAPI *pIcmpSendEcho)
(HANDLE,DWORD,LPVOID,WORD,PIPINFO,LPVOID,DWORD,DWORD);
HANDLE hndlIcmp; // LoadLibrary() handle to ICMP.DLL
WSADATA wsaData; // WSADATA
struct in_addr iaDest; // Internet address structure
LPHOSTENT pHost; // Pointer to host entry structure
DWORD *dwAddress; // IP Address
HANDLE hndlFile; // Handle for IcmpCreateFile()
// Dynamically load the ICMP.DLL
hndlIcmp = LoadLibrary("ICMP.DLL");
if (hndlIcmp == NULL)
{
sprintf(pPingInfo->cErrorMessage, "Could not load ICMP.DLL!");
return( PING_ERROR_SOCKET );
}
// Retrieve ICMP function pointers
pIcmpCreateFile = (HANDLE (WINAPI *)(void))
GetProcAddress((HMODULE)hndlIcmp,"IcmpCreateFile");
pIcmpCloseHandle = (BOOL (WINAPI *)(HANDLE))
GetProcAddress((HMODULE)hndlIcmp,"IcmpCloseHandle");
pIcmpSendEcho = (DWORD (WINAPI *)
(HANDLE,DWORD,LPVOID,WORD,PIPINFO,LPVOID,DWORD,DWORD))
GetProcAddress((HMODULE)hndlIcmp,"IcmpSendEcho");
// Check all the function pointers
if (pIcmpCreateFile == NULL ||
pIcmpCloseHandle == NULL ||
pIcmpSendEcho == NULL)
{
sprintf(pPingInfo->cErrorMessage, "Error loading ICMP.DLL functions!");
FreeLibrary((HMODULE)hndlIcmp);
return( PING_ERROR_SOCKET );
}
// Init WinSock
if (WSAStartup(PING_WINSOCK_VERSION, &wsaData))
{
sprintf(pPingInfo->cErrorMessage, "Winsock could not be initialized!");
WSACleanup();
return( PING_ERROR_SOCKET );
}
// Check WinSock version
if (0x0101 != wsaData.wVersion)
{
sprintf(pPingInfo->cErrorMessage, "No WinSock version 1.1 support found!");
WSACleanup();
FreeLibrary((HMODULE)hndlIcmp);
return( PING_ERROR_SOCKET );
}
// Resovling the Host
iaDest.s_addr = inet_addr(pPingInfo->cHostName);
if (iaDest.s_addr == INADDR_NONE)
pHost = gethostbyname(pPingInfo->cHostName);
else
pHost = gethostbyaddr((const char *)&iaDest,
sizeof(struct in_addr), AF_INET);
if (pHost == NULL)
{
sprintf(pPingInfo->cErrorMessage, "Unable resolve host %s!", pPingInfo->cHostName);
FreeLibrary((HMODULE)hndlIcmp);
WSACleanup();
return( PING_ERROR_SOCKET );
}
// Copy the IP address
dwAddress = (DWORD *)(*pHost->h_addr_list);
// Get an ICMP echo request handle
hndlFile = pIcmpCreateFile();
if(hndlFile < 0)
{
sprintf(pPingInfo->cErrorMessage, "Unable get ICMP handle!");
FreeLibrary((HMODULE)hndlIcmp);
WSACleanup();
return( PING_ERROR_SOCKET );
}
// Start to Ping
unsigned char request_data[PING_REQ_DATASIZE];
unsigned char reBuff[sizeof(ICMPECHO)+200];
IPINFO ipInfo; // IP Options structure
ICMPECHO *icmpEcho = NULL; // ICMP Echo reply buffer
memset(reBuff, 0, sizeof(ICMPECHO)+200);
memset(request_data, 0, sizeof(request_data));
memset(&ipInfo, 0, sizeof(ipInfo));
ipInfo.Ttl = 255;
ipInfo.Options = request_data;
pIcmpSendEcho(
hndlFile, // Handle from IcmpCreateFile()
*dwAddress, // Destination IP address
request_data, // Pointer to buffer to send
sizeof(request_data), // Size of buffer in bytes
&ipInfo, // Request options
reBuff, // Reply buffer
sizeof(reBuff),
1000); // Time to wait in milliseconds
icmpEcho = (ICMPECHO *) reBuff;
// Get the results
iaDest.s_addr = icmpEcho->Source;
sprintf(pPingInfo->cIpAddress, "%s", inet_ntoa(iaDest));
if (icmpEcho->Status)
{
sprintf(pPingInfo->cErrorMessage, "%d - Request timed out.", icmpEcho->Status);
pPingInfo->blTimouted = TRUE;
pPingInfo->nReplyBytes = pPingInfo->nReplyTTL = 0;
pPingInfo->nReplyTime = 0;
}
else
{
sprintf(pPingInfo->cErrorMessage, "No Error!");
pPingInfo->blTimouted = FALSE;
pPingInfo->nReplyBytes = icmpEcho->DataSize;
pPingInfo->nReplyTTL = icmpEcho->ipInfo.Ttl;
pPingInfo->nReplyTime = icmpEcho->RTTime;
}
// Close the echo request file handle
pIcmpCloseHandle(hndlFile);
FreeLibrary((HMODULE)hndlIcmp);
WSACleanup();
return pPingInfo->blTimouted ? PING_ERROR_TIMEOUT : PING_ERROR_SUCCESS ;
}
Regards,
Hanney
|
|
|
|
|
Hi,Sonu,
I'm trying to find your message in the forums, but I failed. So I reply your message here, sorry for the late reply.
To answer your question, one point I need to clarify is the codes I post can run 2 instances in one App, but for the code of Norm Almond, I encountered an error while 1 of 2 host is NOT active, the code will drop into a dead loop in "recvfrom" (RecvEchoReply).
I made a small changes for WinPing so that it can detect which packet it should response, the key is "ID" of ICMPHDR structure, while you send ICMP request, this member data should be filled in your own process(or Thread) ID.
1) in CPing::SendEchoRequest, replace the "nID++" with your own thread ID
echoReq.icmpHdr.ID = (USHORT)GetCurrentThreadId();
2) in "DWORD CPing::RecvEchoReply" detect your own packet:
for(;;)
{
// Receive the echo reply
nRet = recvfrom(s, // socket
(LPSTR)&echoReply, // buffer
sizeof(ECHOREPLY), // size of buffer
0, // flags
(LPSOCKADDR)lpsaFrom, // From address
&nAddrLen); // pointer to address len
if( echoReply.echoRequest.icmpHdr.ID == (USHORT)GetCurrentThreadId() ) break;
// If NOT equal, it's someone else packet
}
Hope it can answer your question, any question, please send me email.
Best Regards,
Hanney Wang
|
|
|
|
|
thanks for the code. It worked very well. I have send you an another email. Please let me know about that.
thanks
da sonu
|
|
|
|
|
It seems not to be a good idea to put recvfrom in an infinite loop.
My solution:
(before calling WaitForEchoReply in CPing::Ping)
m_dwStart = GetTickCount();
m_dwStart is a private member of CPing.
(in the for(;;) loop)
if (GetTickCount() - m_dwStart > 1000)<br />
{<br />
break;<br />
}
|
|
|
|
|
I am beginner programmer from Polish. I began work over my newprogramme and I hit on little trouble. I must place data (HTML code) in indicator WebBrowser2. Does not go me here for loading of file HTML from disc with method Navigte( 2,...). I want to know how must I implement a code to transfer HTML code from board eg CStringArray to WebBrowser2. If You can help, please write back.
|
|
|
|
|
Hi
I am system Administrator.we are supplying internet to customers.how can i control the bandwidth supply to users ,of varying subcribtion.
Now every customer is getting the full bandwidth regardless of his subcribtion.Please help in this matter.
can we control the bandwidth speed thru server programming like ASP or XML.
with regards
balaje.R.P
|
|
|
|
|
Not the right place to ask such a question.
|
|
|
|
|
Please help me in finding the ip of the local host.
-C
|
|
|
|
|
127.0.0.1
|
|
|
|
|
TRY:
void DiscoverLocalIP()
{
TCHAR szHostName[1024];
//first get the local host's name
int res = gethostname(szHostName , 1024);
if (res == 0)
{
//then get the host's information by its name
HOSTENT *phost = gethostbyname(szHostName);
if (phost)
{
//phost->h_addr_list records the host's IP array
for( int i = 0; phost->h_addr_list[i] != 0; i++ )
{
//here we get each of the host's IP which is in network byte order
ULONG ulIP = *(ULONG *)phost->h_addr_list[i];
}
}
}
}
Don't forget to initialize WinSock library before call these WinSock APIs.
BTW,127.0.0.1 is only the roll_back address.
Cheers
|
|
|
|
|
loopback..
|
|
|
|
|
Dear Sir
How to get the ping result shown with current time and continuously get result at a time interval like 15 minutes?
Shown like this(15 minutes interval):
Reply from:123.456.12.34; bytes=32 time=1111ms TTL=123,at 12:00am,05/19/2002
Reply from:123.456.12.34; bytes=32 time=1222ms TTL=123,at 12:15am,05/19/2002
and so on.
Thanks a lot!!!!!
XYZ
|
|
|
|
|
It's a bug, I know about it and when I get round to updating it I'll fix the code.
Normski. - Professional Windows Programmer
|
|
|
|
|
Hi Norm,
great class, but there's one simple but effective problem... Under Windows 2000 you can only send a ping as an administrator (and so does WinNT4 i guess...).
Under WinNT4.0, MSDN gives a workaround.
Any ideas for win2000 ????
thx,
Olli
|
|
|
|
|
I've just had an quick look, and found CPing class by P.J.Naughter - it uses IcmpSendEcho function for ping-ing. It does work on WinXP. But I think, that this function is not included on Windows 95/98/Me/NT.
|
|
|
|
|
i've tha same problem, i've noticed there's no way to work with setsockopt and sendto too under winNT4 without administrator accounts. All works fine by using administrator account, but it's not a solution.
Can someone tell me a trick to solve the problem or just a place to find more infos??
thanx D
|
|
|
|
|
|
I guess the thread is wrong anywhere. I test it on win98, and it does work!
|
|
|
|
|
Hi All,
I have a process which needs to know the CPU usage and Memory consumption of the process itself as well as other known processes in the system.
Can anyone help me and tell me on All windows based OS how this can be done.
Thanks in advance for any help.
A Guy
|
|
|
|
|
In your winping program you had a great class for handling your combo box. I've added the class to my program yet when I add selection to the combo box, then choose the down arrow it leaves a blank space then the new selection and any others that I may have typed in. Where are you setting how many positions are in the combobox? Hope this makes sense.
Tom Wright
Network Technical Services / Programmer
tawright915@yahoo.com
|
|
|
|
|
How to find the Machine IP Address.A function which finds the Maching IP address.
|
|
|
|
|
I presume the input is machine name. If so, we can find the ip address using the following Win32 API's.
GetMacAddress(strMachineName, F1, F2, F3, F4)
where F1..F4 are of type BYTE and strMachineName is a char*.
The result 'true' indicate, successfully executed the command.
|
|
|
|
|
WSA Error 10044 comes out
when run in windows 95
may i know what is the cause and how to solve it
thanks
|
|
|
|
|
Anonymous wrote:
WSA Error 10044
Error code means that you tried to use an unsupported function. This will most probably be due not having Windows Sockets version 2.0 (or greater)installed. Go to the microsoft web site and download the latest version of Wsock32.dll. This should fix the problem.
|
|
|
|
|