Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Ping


Автор: Bima 9.10.2006, 12:18
Привет всем.

Прошу откликнуться всех тех, кто писал пинг на ВСВ. Сторонние компоненты не предлагать, нужет чистый код на ВСВ.

Автор: Romikgy 9.10.2006, 12:37
Цитата(Bima @  9.10.2006,  11:18 Найти цитируемый пост)
нужет чистый код на ВСВ. 

что это обозначает?
VCL or WinAPI (Sockets)????

Автор: Bima 9.10.2006, 12:42
можно и WinAPI
я имел ввиду, что бы не предлагали код с использование сторонних компонентов.

Конечно придется использовать WinAPI, но с привязкой к VCL

Автор: Romikgy 9.10.2006, 12:47
Цитата(Bima @  9.10.2006,  11:42 Найти цитируемый пост)
с привязкой к VCL 

к каким VCL встроеным в билдер?

Автор: Bima 9.10.2006, 12:51
ко всем в стандартной комлектации... 

Автор: Romikgy 9.10.2006, 12:52
http://www.sources.ru/cpp/cpp_cping.shtml
http://forum.sources.ru/index.php?showtopic=157027&st=0&#entry1295991
чистый апи имхо , но дельфи
http://www.ishodniki.ru/art/artshow.php?cat=1&id=76&show=delphi
http://forum.vingrad.ru/index.php?showtopic=89605&hl=
http://forum.vingrad.ru/index.php?showtopic=26584&hl=
http://forum.vingrad.ru/index.php?showtopic=3486&hl=

не брезгуем поиском! 

Автор: Bima 9.10.2006, 13:24
Вот что получилось:

на форму кинул label и Edit
код основной программы:
Код

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "Kod.h"
#include "Cping.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
CPing ping;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner){}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
BOOL bResult = ping.Ping(Edit1->Text.c_str());
if( bResult )
   {
   Application->MessageBox("Good","Information",MB_ICONINFORMATION+MB_SYSTEMMODAL);
   }
else
   {
   Application->MessageBox("Error","Error",MB_ICONWARNING);
   }
}
//---------------------------------------------------------------------------


код класса CPing
Код

#include "CPing.h"

CPing::CPing()
{
    bValid = FALSE;
    WSADATA wsaData;            // WSADATA
    int nRet;                    // General use return code

    // Dynamically load the ICMP.DLL
    hndlIcmp = LoadLibrary("ICMP.DLL");
    if (hndlIcmp == NULL)
    {
        ::MessageBox(NULL, "Could not load ICMP.DLL", "Error:", MB_OK);
        return;
    }
    // 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)
    {
        ::MessageBox(NULL, "Error loading ICMP.DLL", "Error:", MB_OK);
        FreeLibrary((HMODULE)hndlIcmp);
        return;
    }

    // Init WinSock
    nRet = WSAStartup(0x0101, &wsaData );
    if (nRet)
    {
        ::MessageBox(NULL, "WSAStartup() error:", "Error:", MB_OK);
        WSACleanup();
        FreeLibrary((HMODULE)hndlIcmp);
        return;
    }
    // Check WinSock version
    if (0x0101 != wsaData.wVersion)
    {
        ::MessageBox(NULL, "No WinSock version 1.1 support found", "Error:", MB_OK);
        WSACleanup();
        FreeLibrary((HMODULE)hndlIcmp);
        return;
    }
    bValid = TRUE;
}

CPing::~CPing()
{
    WSACleanup();
    FreeLibrary((HMODULE)hndlIcmp);
}

int CPing::Ping(char* strHost)
{
    struct in_addr iaDest;        // Internet address structure
    LPHOSTENT pHost;            // Pointer to host entry structure
    DWORD *dwAddress;            // IP Address
    IPINFO ipInfo;                // IP Options structure
    ICMPECHO icmpEcho;            // ICMP Echo reply buffer
    HANDLE hndlFile;            // Handle for IcmpCreateFile()

    if(!bValid)
    {
        return FALSE;
    }

    // Lookup destination
    // Use inet_addr() to determine if we're dealing with a name
    // or an address
    iaDest.s_addr = inet_addr(strHost);
    if (iaDest.s_addr == INADDR_NONE)
        pHost = gethostbyname(strHost);
    else
        pHost = gethostbyaddr((const char *)&iaDest, 
                        sizeof(struct in_addr), AF_INET);
    if (pHost == NULL)
    {
        return FALSE;
    }

    // Copy the IP address
    dwAddress = (DWORD *)(*pHost->h_addr_list);

    // Get an ICMP echo request handle        
    hndlFile = pIcmpCreateFile();

    // Set some reasonable default values
    ipInfo.Ttl = 255;
    ipInfo.Tos = 0;
    ipInfo.IPFlags = 0;
    ipInfo.OptSize = 0;
    ipInfo.Options = NULL;
    icmpEcho.Status = 0;
    // Reqest an ICMP echo
    pIcmpSendEcho(
        hndlFile,        // Handle from IcmpCreateFile()
        *dwAddress,        // Destination IP address
        NULL,            // Pointer to buffer to send
        0,                // Size of buffer in bytes
        &ipInfo,        // Request options
        &icmpEcho,        // Reply buffer
        sizeof(struct tagICMPECHO),
        1000);            // Time to wait in milliseconds
    // Print the results
    iaDest.s_addr = icmpEcho.Source;
    if (icmpEcho.Status)
    {
        return FALSE;
    }

    // Close the echo request file handle
    pIcmpCloseHandle(hndlFile);
    return TRUE;
}


код заголовочного файла для класса CPing:
Код

#ifndef CPING_H
#define CPING_H

//#include "StdAfx.h" заремировал, так как здесь используется класс MFC
#include <windows.h> //Вставил, что бы заработала программа
#include <winsock.h>  //Вставил, что бы заработала программа

typedef struct tagIPINFO
{
    u_char Ttl;                // Time To Live
    u_char Tos;                // Type Of Service
    u_char IPFlags;            // IP flags
    u_char OptSize;            // Size of options data
    u_char FAR *Options;    // Options data buffer
}IPINFO;

typedef IPINFO* PIPINFO;

typedef struct tagICMPECHO
{
    u_long Source;            // Source address
    u_long Status;            // IP status
    u_long RTTime;            // Round trip time in milliseconds
    u_short DataSize;        // Reply data size
    u_short Reserved;        // Unknown
    void FAR *pData;        // Reply data buffer
    IPINFO    ipInfo;            // Reply options
}ICMPECHO;

typedef ICMPECHO* PICMPECHO;

class CPing
{
public:
    CPing();
    ~CPing();
    BOOL Ping(char* strHost);
private:
    // ICMP.DLL Export Function Pointers
    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
    BOOL bValid; // if it doesn't construct properly, it won't be valid
};
#endif


Теперь сам вопрос: Каким образом вызывать функцию в своей программе, что бы можно было передавать колличество передаваемых байт и время на таймут? Еще бы хотелось, что бы функция в качестве параметра возвращала сколько мс она тратит на пинг

Автор: Romikgy 9.10.2006, 13:45
добавь в класс еще один метод
Код

int CPing::Pingms(char* strHost)
{
    struct in_addr iaDest;        // Internet address structure
    LPHOSTENT pHost;            // Pointer to host entry structure
    DWORD *dwAddress;            // IP Address
    IPINFO ipInfo;                // IP Options structure
    ICMPECHO icmpEcho;            // ICMP Echo reply buffer
    HANDLE hndlFile;            // Handle for IcmpCreateFile()
    if(!bValid)
    {
        return -1;
    }
    // Lookup destination
    // Use inet_addr() to determine if we're dealing with a name
    // or an address
    iaDest.s_addr = inet_addr(strHost);
    if (iaDest.s_addr == INADDR_NONE)
        pHost = gethostbyname(strHost);
    else
        pHost = gethostbyaddr((const char *)&iaDest, 
                        sizeof(struct in_addr), AF_INET);
    if (pHost == NULL)
    {
        return -1;
    }
    // Copy the IP address
    dwAddress = (DWORD *)(*pHost->h_addr_list);
    // Get an ICMP echo request handle        
    hndlFile = pIcmpCreateFile();
    // Set some reasonable default values
    ipInfo.Ttl = 255;
    ipInfo.Tos = 0;
    ipInfo.IPFlags = 0;
    ipInfo.OptSize = 0;
    ipInfo.Options = NULL;
    icmpEcho.Status = 0;
    // Reqest an ICMP echo
    pIcmpSendEcho(
        hndlFile,        // Handle from IcmpCreateFile()
        *dwAddress,        // Destination IP address
        NULL,            // Pointer to buffer to send
        0,                // Size of buffer in bytes
        &ipInfo,        // Request options
        &icmpEcho,        // Reply buffer
        sizeof(struct tagICMPECHO),
        1000);            // Time to wait in milliseconds
    // Print the results
    iaDest.s_addr = icmpEcho.Source;
    if (icmpEcho.Status)
    {
        return -1;
    }
    // Close the echo request file handle
    pIcmpCloseHandle(hndlFile);
    return icmpEcho.RTTime;
}

Автор: Bima 9.10.2006, 14:03
я понял, что нужно добавлять метод в класс.
Но я бы хотел просто изменить заголовочную функцию int CPing::Ping(char* strHost)
на конструкцию типа вот этой: int CPing::Ping(char* strHost, DWORD mByte, DWORD TimeOut, DWORD *mSek)
где mByte колличество передаваемых и получаемых байт,
TimeOut - время таймаута,
mSek - время затраченное на пинг
все бы ничего, но я не знаю, куда вставлять TimeOut, mSek и mByte smile


Автор: Romikgy 9.10.2006, 14:36
Код

int CPing::Ping(char* strHost, DWORD mByte, DWORD TimeOut, DWORD *mSek)
{
    struct in_addr iaDest;        // Internet address structure
    LPHOSTENT pHost;            // Pointer to host entry structure
    DWORD *dwAddress;            // IP Address
    IPINFO ipInfo;                // IP Options structure
    ICMPECHO icmpEcho;            // ICMP Echo reply buffer
    HANDLE hndlFile;            // Handle for IcmpCreateFile()
    if(!bValid)
    {
        return FALSE;
    }
    // Lookup destination
    // Use inet_addr() to determine if we're dealing with a name
    // or an address
    iaDest.s_addr = inet_addr(strHost);
    if (iaDest.s_addr == INADDR_NONE)
        pHost = gethostbyname(strHost);
    else
        pHost = gethostbyaddr((const char *)&iaDest, 
                        sizeof(struct in_addr), AF_INET);
    if (pHost == NULL)
    {
        return FALSE;
    }
    // Copy the IP address
    dwAddress = (DWORD *)(*pHost->h_addr_list);
    // Get an ICMP echo request handle        
    hndlFile = pIcmpCreateFile();
    // Set some reasonable default values
    ipInfo.Ttl = 255;
    ipInfo.Tos = 0;
    ipInfo.IPFlags = 0;
    ipInfo.OptSize = mByte;
    ipInfo.Options = NULL;// здесь надо имхо выделить сколько байт шлешь
    icmpEcho.Status = 0;
    // Reqest an ICMP echo
    pIcmpSendEcho(
        hndlFile,        // Handle from IcmpCreateFile()
        *dwAddress,        // Destination IP address
        NULL,            // Pointer to buffer to send
        0,                // Size of buffer in bytes
        &ipInfo,        // Request options
        &icmpEcho,        // Reply buffer
        sizeof(struct tagICMPECHO),
        TimeOut);            // Time to wait in milliseconds
    // Print the results
    iaDest.s_addr = icmpEcho.Source;
    *mSek=RTTime;
    if (icmpEcho.Status)
    {
        return FALSE;
    }
    // Close the echo request file handle
    pIcmpCloseHandle(hndlFile);
    return TRUE;
}


Добавлено @ 14:38 
http://www.citforum.ru/nets/articles/ping/
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/iphlp/iphlp/icmpsendecho.asp

Автор: Bima 10.10.2006, 06:17
ничего не выходит.

сначала ничего скомпилировать не мог.
Потом заменил строку *mSek=RTTime;
на *mSek=icmpEcho.RTTime;
скомпилировалось хорошо.

Вызываю вот так
Код

DWORD *p;
BOOL bResult = ping.Ping(Edit1->Text.c_str(), 5, 1000, p );
if( bResult )
   {
   Application->MessageBox("Good","Information",MB_ICONINFORMATION+MB_SYSTEMMODAL);
   Label2->Caption=IntToStr(p);//здесь пытаюсь получить время ответа
   }
else
   {
   Application->MessageBox("Error","Error",MB_ICONWARNING);
   }


но при вызове этой функции происходит исключение в моей программе и тормозится smile

Автор: Romikgy 10.10.2006, 09:00
Цитата(Bima @  10.10.2006,  05:17 Найти цитируемый пост)
 Label2->Caption=IntToStr(p);//здесь пытаюсь получить время ответа
   }

здесь надо Label2->Caption=IntToStr(*p);  smile  smile  smile 
и 
Цитата(Bima @  10.10.2006,  05:17 Найти цитируемый пост)
этой функции происходит исключение

потому 
Цитата(Romikgy @  9.10.2006,  13:36 Найти цитируемый пост)
 ipInfo.Options = NULL;// здесь надо имхо выделить сколько байт шлешь

 smile  smile  smile 

Автор: Romikgy 10.10.2006, 09:19
Код

int CPing::Ping(char* strHost, DWORD mByte, DWORD TimeOut, DWORD *mSek)
{
    struct in_addr iaDest;        // Internet address structure
    LPHOSTENT pHost;            // Pointer to host entry structure
    DWORD *dwAddress;            // IP Address
    IPINFO ipInfo;                // IP Options structure
    ICMPECHO icmpEcho;            // ICMP Echo reply buffer
    HANDLE hndlFile;            // Handle for IcmpCreateFile()
    if(!bValid)
    {
        return FALSE;
    }
    // Lookup destination
    // Use inet_addr() to determine if we're dealing with a name
    // or an address
    iaDest.s_addr = inet_addr(strHost);
    if (iaDest.s_addr == INADDR_NONE)
        pHost = gethostbyname(strHost);
    else
        pHost = gethostbyaddr((const char *)&iaDest, 
                        sizeof(struct in_addr), AF_INET);
    if (pHost == NULL)
    {
        return FALSE;
    }
    // Copy the IP address
    dwAddress = (DWORD *)(*pHost->h_addr_list);
    // Get an ICMP echo request handle        
    hndlFile = pIcmpCreateFile();
    // Set some reasonable default values
    ipInfo.Ttl = 255;
    ipInfo.Tos = 0;
    ipInfo.IPFlags = 0;
    ipInfo.OptSize = mByte;
    if (mByte)
    ipInfo.Options = new unsigned char[mByte];// çäåñü íàäî èìõî âûäåëèòü ñêîëüêî áàéò øëåøü
    else
    ipInfo.Options = NULL;
    icmpEcho.Status = 0;
    // Reqest an ICMP echo
    pIcmpSendEcho(
        hndlFile,        // Handle from IcmpCreateFile()
        *dwAddress,        // Destination IP address
        NULL,            // Pointer to buffer to send
        0,                // Size of buffer in bytes
        &ipInfo,        // Request options
        &icmpEcho,        // Reply buffer
        sizeof(struct tagICMPECHO),
        TimeOut);            // Time to wait in milliseconds
    // Print the results
    iaDest.s_addr = icmpEcho.Source;
    *mSek=icmpEcho.RTTime;
    if (icmpEcho.Status)
    {
        return FALSE;
    }
    // Close the echo request file handle
    if (mByte)
    delete [] ipInfo.Options;
    pIcmpCloseHandle(hndlFile);
    return TRUE;
}

использование
Код

DWORD lll;
 ping.Ping("192.168.12.1",100,1000,&lll);
 Edit1->Text=IntToStr(lll);

Автор: Bima 10.10.2006, 09:52
все отлично, код заработал, но практически всегда выдает, что функция закончилась неудачно (False)
Хотя время таймаута до 10 секунд ставлю, а возвращается от 20 до 70 мс
Код

DWORD p;
BOOL bResult = ping.Ping(Edit1->Text.c_str(), 1, 10000, &p );
Label4->Caption=IntToStr(p); // время затраченое на пинг в любом случае
if( bResult )
   {
   Application->MessageBox("Good","Information",MB_ICONINFORMATION+MB_SYSTEMMODAL);
   Label2->Caption=IntToStr(p); // время затраченое на пинг в случае удачной передачи
   }
else
   {
   Application->MessageBox("Error","Error",MB_ICONWARNING);
   }


Почему функция возвращает False???

Автор: Romikgy 10.10.2006, 10:13
Цитата(Romikgy @  10.10.2006,  08:19 Найти цитируемый пост)
pIcmpSendEcho(

возвращает ответ где статус ответа
Код

//
// IP_STATUS codes returned from IP APIs
//

#define IP_STATUS_BASE              11000

#define IP_SUCCESS                  0
#define IP_BUF_TOO_SMALL            (IP_STATUS_BASE + 1)
#define IP_DEST_NET_UNREACHABLE     (IP_STATUS_BASE + 2)
#define IP_DEST_HOST_UNREACHABLE    (IP_STATUS_BASE + 3)
#define IP_DEST_PROT_UNREACHABLE    (IP_STATUS_BASE + 4)
#define IP_DEST_PORT_UNREACHABLE    (IP_STATUS_BASE + 5)
#define IP_NO_RESOURCES             (IP_STATUS_BASE + 6)
#define IP_BAD_OPTION               (IP_STATUS_BASE + 7)
#define IP_HW_ERROR                 (IP_STATUS_BASE + 8)
#define IP_PACKET_TOO_BIG           (IP_STATUS_BASE + 9)
#define IP_REQ_TIMED_OUT            (IP_STATUS_BASE + 10)
#define IP_BAD_REQ                  (IP_STATUS_BASE + 11)
#define IP_BAD_ROUTE                (IP_STATUS_BASE + 12)
#define IP_TTL_EXPIRED_TRANSIT      (IP_STATUS_BASE + 13)
#define IP_TTL_EXPIRED_REASSEM      (IP_STATUS_BASE + 14)
#define IP_PARAM_PROBLEM            (IP_STATUS_BASE + 15)
#define IP_SOURCE_QUENCH            (IP_STATUS_BASE + 16)
#define IP_OPTION_TOO_BIG           (IP_STATUS_BASE + 17)
#define IP_BAD_DESTINATION          (IP_STATUS_BASE + 18)

 IP_SUCCESS                  0 это при успешном завершении ф_ции, если верить мсдн smile
это из файла ipexport.h

Автор: Bima 10.10.2006, 10:32
проверил переменную
возвращает 11007 (IP_BAD_OPTION)
и что это значит???

Автор: Romikgy 10.10.2006, 11:36
замени на это , думаю найдешь где
Код

if (mByte)
    {
    ipInfo.Options = new unsigned char[mByte];// çäåñü íàäî èìõî âûäåëèòü ñêîëüêî áàéò øëåøü
    memset(ipInfo.Options,0,mByte);
    }
    else
    ipInfo.Options = NULL;

Автор: Bima 10.10.2006, 13:41
Все заработало.
Вот универсальный код программы, который можно использовать:

Создаем новый проект
кидаем на форму Edit и Button

добавляем к проекту два файла:
cping.cpp
Код

#include "CPing.h"
//---------------------------------------------------------------------------
CPing::CPing()
{
bValid = FALSE;
WSADATA wsaData;            // WSADATA
int nRet;                    // General use return code

hndlIcmp = LoadLibrary("ICMP.DLL"); // Dynamically load the ICMP.DLL
if (hndlIcmp == NULL)
   {
   ::MessageBox(NULL, "Could not load ICMP.DLL", "Error:", MB_OK);
   return;
   }
// 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)
{
   ::MessageBox(NULL, "Error loading ICMP.DLL", "Error:", MB_OK);
   FreeLibrary((HMODULE)hndlIcmp);
   return;
}

nRet = WSAStartup(0x0101, &wsaData ); // Init WinSock
if (nRet)
   {
   ::MessageBox(NULL, "WSAStartup() error:", "Error:", MB_OK);
   WSACleanup();
   FreeLibrary((HMODULE)hndlIcmp);
   return;
   }
    
if (0x0101 != wsaData.wVersion)  // Check WinSock version
   {
   ::MessageBox(NULL, "No WinSock version 1.1 support found", "Error:", MB_OK);
   WSACleanup();
   FreeLibrary((HMODULE)hndlIcmp);
   return;
   }
bValid = TRUE;
}
//---------------------------------------------------------------------------
CPing::~CPing()
{
WSACleanup();
FreeLibrary((HMODULE)hndlIcmp);
}
//---------------------------------------------------------------------------
int CPing::Ping(char* strHost, DWORD mByte, DWORD TimeOut, DWORD *mSek)
{
struct in_addr iaDest;  // Internet address structure
LPHOSTENT pHost;        // Pointer to host entry structure
DWORD *dwAddress;       // IP Address
IPINFO ipInfo;          // IP Options structure
ICMPECHO icmpEcho;      // ICMP Echo reply buffer
HANDLE hndlFile;        // Handle for IcmpCreateFile()

if(!bValid)             //Если создание класса произошло успешно то можно пинговать
   {
   return No_Create_Class;  //возвращаем 100 (No_Create_Class)
   }

iaDest.s_addr = inet_addr(strHost);
if (iaDest.s_addr == INADDR_NONE)
    pHost = gethostbyname(strHost);
else
    pHost = gethostbyaddr((const char *)&iaDest, sizeof(struct in_addr), AF_INET);
if (pHost == NULL)
   {
   return Error_Host;
   }

dwAddress = (DWORD *)(*pHost->h_addr_list); // Copy the IP address
hndlFile = pIcmpCreateFile(); // Get an ICMP echo request handle

ipInfo.Ttl = 255;
ipInfo.Tos = 0;
ipInfo.IPFlags = 0;
ipInfo.OptSize = mByte;
if (mByte)
  {
  ipInfo.Options = new unsigned char[mByte];// выделяем память
  memset(ipInfo.Options,0,mByte);
  }
else
  ipInfo.Options = NULL;

icmpEcho.Status = 0;

pIcmpSendEcho(
    hndlFile,     // Handle from IcmpCreateFile()
    *dwAddress,   // Destination IP address
    NULL,         // Pointer to buffer to send
    0,            // Size of buffer in bytes
    &ipInfo,      // Request options
    &icmpEcho,    // Reply buffer
    sizeof(struct tagICMPECHO),
    TimeOut);     // Time to wait in milliseconds

iaDest.s_addr = icmpEcho.Source;
*mSek=icmpEcho.RTTime;

if (mByte)
   delete [] ipInfo.Options;

if (icmpEcho.Status!=0)
   {
//**************************************
//весь switch можно заремировать
//**************************************
   switch (icmpEcho.Status)
      {
      case No_Create_Class :
         ::MessageBox(NULL, "Class not create","Error",MB_ICONWARNING);
         break;
      case Error_Host :
         ::MessageBox(NULL, "Error Host","Error",MB_ICONWARNING);
         break;
      case IP_BUF_TOO_SMALL :
         ::MessageBox(NULL, "IP_BUF_TOO_SMALL","Error",MB_ICONWARNING);
         break;
      case IP_DEST_NET_UNREACHABLE :
         ::MessageBox(NULL, "IP_DEST_NET_UNREACHABLE","Error",MB_ICONWARNING);
         break;
      case IP_DEST_HOST_UNREACHABLE :
         ::MessageBox(NULL, "IP_DEST_HOST_UNREACHABLE","Error",MB_ICONWARNING);
         break;
      case IP_DEST_PROT_UNREACHABLE :
         ::MessageBox(NULL, "IP_DEST_PROT_UNREACHABLE","Error",MB_ICONWARNING);
         break;
      case IP_DEST_PORT_UNREACHABLE :
         ::MessageBox(NULL, "IP_DEST_PORT_UNREACHABLE","Error",MB_ICONWARNING);
         break;
      case IP_NO_RESOURCES :
         ::MessageBox(NULL, "IP_NO_RESOURCES","Error",MB_ICONWARNING);
         break;
      case IP_BAD_OPTION :
         ::MessageBox(NULL, "IP_BAD_OPTION","Error",MB_ICONWARNING);
         break;
      case IP_HW_ERROR :
         ::MessageBox(NULL, "IP_HW_ERROR","Error",MB_ICONWARNING);
         break;
      case IP_PACKET_TOO_BIG :
         ::MessageBox(NULL, "IP_PACKET_TOO_BIG","Error",MB_ICONWARNING);
         break;
      case IP_REQ_TIMED_OUT :
         ::MessageBox(NULL, "IP_REQ_TIMED_OUT","Error",MB_ICONWARNING);
         break;
      case IP_BAD_REQ :
         ::MessageBox(NULL, "IP_BAD_REQ","Error",MB_ICONWARNING);
         break;
      case IP_BAD_ROUTE :
         ::MessageBox(NULL, "IP_BAD_ROUTE","Error",MB_ICONWARNING);
         break;
      case IP_TTL_EXPIRED_TRANSIT :
         ::MessageBox(NULL, "IP_TTL_EXPIRED_TRANSIT","Error",MB_ICONWARNING);
         break;
      case IP_TTL_EXPIRED_REASSEM :
         ::MessageBox(NULL, "IP_TTL_EXPIRED_REASSEM","Error",MB_ICONWARNING);
         break;
      case IP_PARAM_PROBLEM :
         ::MessageBox(NULL, "IP_PARAM_PROBLEM","Error",MB_ICONWARNING);
         break;
      case IP_SOURCE_QUENCH :
         ::MessageBox(NULL, "IP_SOURCE_QUENCH","Error",MB_ICONWARNING);
         break;
      case IP_OPTION_TOO_BIG :
         ::MessageBox(NULL, "IP_OPTION_TOO_BIG","Error",MB_ICONWARNING);
         break;
      case IP_BAD_DESTINATION :
         ::MessageBox(NULL, "IP_BAD_DESTINATION","Error",MB_ICONWARNING);
         break;

      default :
         ::MessageBox(NULL, "Error","Error",MB_ICONWARNING);
      }
//**************************************
   return icmpEcho.Status;
   }
pIcmpCloseHandle(hndlFile);
return 0;
}
//---------------------------------------------------------------------------


cping.h
Код

#ifndef CPING_H
#define CPING_H
#define No_Create_Class       100
#define Error_Host            101

//#include "StdAfx.h"
#include <windows.h>
#include <winsock.h>
#include <ipexport.h>

typedef struct tagIPINFO
{
    u_char Ttl;                // Time To Live
    u_char Tos;                // Type Of Service
    u_char IPFlags;      // IP flags
    u_char OptSize;      // Size of options data
    u_char FAR *Options;    // Options data buffer
}IPINFO;

typedef IPINFO* PIPINFO;

typedef struct tagICMPECHO
{
    u_long Source;            // Source address
    u_long Status;            // IP status
    u_long RTTime;            // Round trip time in milliseconds
    u_short DataSize;        // Reply data size
    u_short Reserved;        // Unknown
    void FAR *pData;        // Reply data buffer
    IPINFO    ipInfo;     // Reply options
}ICMPECHO;

typedef ICMPECHO* PICMPECHO;

class CPing
{
public:
    CPing();
    ~CPing();
    int CPing::Ping(char* strHost, DWORD mByte, DWORD TimeOut, DWORD *mSek);
private:
    // ICMP.DLL Export Function Pointers
    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
    BOOL bValid;         // if it doesn't construct properly, it won't be valid
};

#endif


Теперь делаем обработчик на кнопке куда записываем код
Здесь код основной программы:
Код

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "Kod.h"
#include "Cping.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
CPing ping;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner){}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
DWORD p;
AnsiString Otvet;
int bResult = ping.Ping(Edit1->Text.c_str(), 1, 3000, &p);
if (bResult==0)
   {
   Otvet="Ping good ("+IntToStr(p)+"ms)";
   Application->MessageBox(Otvet.c_str() ,"Information",MB_ICONINFORMATION+MB_SYSTEMMODAL);
   }
else
   {
   if (bResult==IP_REQ_TIMED_OUT)
         Application->MessageBox("TimeOut" ,"Information",MB_ICONINFORMATION+MB_SYSTEMMODAL);
   }
}
//---------------------------------------------------------------------------

Автор: Romikgy 10.10.2006, 14:20
Bima, оно работает но не правильно , 
после н-ного промежутка времени и работы со снифером добился работы нормальной 
Код

int CPing::Ping(char* strHost, DWORD mByte, DWORD TimeOut, DWORD *mSek)
{
    struct in_addr iaDest;        // Internet address structure
    LPHOSTENT pHost;            // Pointer to host entry structure
    DWORD *dwAddress;            // IP Address
    IPINFO ipInfo;                // IP Options structure
    ICMPECHO *icmpEcho;            // ICMP Echo reply buffer
    HANDLE hndlFile;            // Handle for IcmpCreateFile()
    if(!bValid)
    {
        return FALSE;
    }
    // Lookup destination
    // Use inet_addr() to determine if we're dealing with a name
    // or an address
    iaDest.s_addr = inet_addr(strHost);
    if (iaDest.s_addr == INADDR_NONE)
        pHost = gethostbyname(strHost);
    else
        pHost = gethostbyaddr((const char *)&iaDest, 
                        sizeof(struct in_addr), AF_INET);
    if (pHost == NULL)
    {
        return FALSE;
    }
    // Copy the IP address
    dwAddress = (DWORD *)(*pHost->h_addr_list);
    // Get an ICMP echo request handle        
    hndlFile = pIcmpCreateFile();
    // Set some reasonable default values
    ipInfo.Ttl = 255;
    ipInfo.Tos = 0;
    ipInfo.IPFlags = 0;
    ipInfo.OptSize = 0;
    ipInfo.Options = NULL;
    icmpEcho=(ICMPECHO*) new char [sizeof(ICMPECHO)+ mByte];
    //icmpEcho = 0;
    //memset(&icmpEcho,0,sizeof(icmpEcho));
    // Reqest an ICMP echo
    char *x=NULL;

    if (mByte) {x=new char[mByte];
    memset(x,'A',mByte);
    }
    pIcmpSendEcho(
        hndlFile,        // Handle from IcmpCreateFile()
        *dwAddress,        // Destination IP address
        x,            // Pointer to buffer to send
        mByte,                // Size of buffer in bytes
        &ipInfo,        // Request options
        icmpEcho,        // Reply buffer
        sizeof(struct tagICMPECHO)+mByte,
        TimeOut);            // Time to wait in milliseconds
    if (mByte) {delete [] x;}
    // Print the results
    iaDest.s_addr = icmpEcho->Source;
    *mSek=icmpEcho->RTTime;
    if (icmpEcho->Status)
    {
        return FALSE;
    }
    // Close the echo request file handle
    //if (mByte)     delete [] ipInfo.Options;
    pIcmpCloseHandle(hndlFile);
    delete [] icmpEcho;
    return TRUE;
}

Автор: Bima 10.10.2006, 14:57
Romikgy, спасибо.
вот исправленная рабочая версия:

Создаем новый проект
кидаем на форму Edit и Button

добавляем к проекту два файла:
cping.cpp
Код

#include "CPing.h"
//---------------------------------------------------------------------------
CPing::CPing()
{
bValid = FALSE;
WSADATA wsaData;            // WSADATA
int nRet;                    // General use return code

hndlIcmp = LoadLibrary("ICMP.DLL"); // Dynamically load the ICMP.DLL
if (hndlIcmp == NULL)
   {
   ::MessageBox(NULL, "Could not load ICMP.DLL", "Error:", MB_OK);
   return;
   }
// 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)
{
   ::MessageBox(NULL, "Error loading ICMP.DLL", "Error:", MB_OK);
   FreeLibrary((HMODULE)hndlIcmp);
   return;
}

nRet = WSAStartup(0x0101, &wsaData ); // Init WinSock
if (nRet)
   {
   ::MessageBox(NULL, "WSAStartup() error:", "Error:", MB_OK);
   WSACleanup();
   FreeLibrary((HMODULE)hndlIcmp);
   return;
   }
    
if (0x0101 != wsaData.wVersion)  // Check WinSock version
   {
   ::MessageBox(NULL, "No WinSock version 1.1 support found", "Error:", MB_OK);
   WSACleanup();
   FreeLibrary((HMODULE)hndlIcmp);
   return;
   }
bValid = TRUE;
}
//---------------------------------------------------------------------------
CPing::~CPing()
{
WSACleanup();
FreeLibrary((HMODULE)hndlIcmp);
}
//---------------------------------------------------------------------------
int CPing::Ping(char* strHost, DWORD mByte, DWORD TimeOut, DWORD *mSek)
{
struct in_addr iaDest;  // Internet address structure
LPHOSTENT pHost;        // Pointer to host entry structure
DWORD *dwAddress;       // IP Address
IPINFO ipInfo;          // IP Options structure
ICMPECHO *icmpEcho;      // ICMP Echo reply buffer
HANDLE hndlFile;        // Handle for IcmpCreateFile()

if(!bValid)             //Если создание класса произошло успешно то можно пинговать
   {
   return No_Create_Class;  //возвращаем 100 (No_Create_Class)
   }

iaDest.s_addr = inet_addr(strHost);
if (iaDest.s_addr == INADDR_NONE)
    pHost = gethostbyname(strHost);
else
    pHost = gethostbyaddr((const char *)&iaDest, sizeof(struct in_addr), AF_INET);
if (pHost == NULL)
   {
   return Error_Host;
   }

dwAddress = (DWORD *)(*pHost->h_addr_list); // Copy the IP address
hndlFile = pIcmpCreateFile(); // Get an ICMP echo request handle

ipInfo.Ttl = 255;
ipInfo.Tos = 0;
ipInfo.IPFlags = 0;
ipInfo.OptSize = 0;
ipInfo.Options = NULL;
icmpEcho=(ICMPECHO*) new char [sizeof(ICMPECHO)+ mByte];
char *x=NULL;

if (mByte)
   {
   x=new char[mByte];
   memset(x,'A',mByte);
   }

pIcmpSendEcho(
   hndlFile,       // Handle from IcmpCreateFile()
   *dwAddress,     // Destination IP address
   x,              // Pointer to buffer to send
   mByte,          // Size of buffer in bytes
   &ipInfo,        // Request options
   icmpEcho,       // Reply buffer
   sizeof(struct tagICMPECHO)+mByte,
   TimeOut);       // Time to wait in milliseconds

if (mByte)
   delete [] x;

iaDest.s_addr = icmpEcho->Source;
*mSek=icmpEcho->RTTime;

if (icmpEcho->Status!=0)
   {
//**************************************
//весь switch можно заремировать
//**************************************
   switch (icmpEcho->Status)
      {
      case No_Create_Class :
         ::MessageBox(NULL, "Class not create","Error",MB_ICONWARNING);
         break;
      case Error_Host :
         ::MessageBox(NULL, "Error Host","Error",MB_ICONWARNING);
         break;
      case IP_BUF_TOO_SMALL :
         ::MessageBox(NULL, "IP_BUF_TOO_SMALL","Error",MB_ICONWARNING);
         break;
      case IP_DEST_NET_UNREACHABLE :
         ::MessageBox(NULL, "IP_DEST_NET_UNREACHABLE","Error",MB_ICONWARNING);
         break;
      case IP_DEST_HOST_UNREACHABLE :
         ::MessageBox(NULL, "IP_DEST_HOST_UNREACHABLE","Error",MB_ICONWARNING);
         break;
      case IP_DEST_PROT_UNREACHABLE :
         ::MessageBox(NULL, "IP_DEST_PROT_UNREACHABLE","Error",MB_ICONWARNING);
         break;
      case IP_DEST_PORT_UNREACHABLE :
         ::MessageBox(NULL, "IP_DEST_PORT_UNREACHABLE","Error",MB_ICONWARNING);
         break;
      case IP_NO_RESOURCES :
         ::MessageBox(NULL, "IP_NO_RESOURCES","Error",MB_ICONWARNING);
         break;
      case IP_BAD_OPTION :
         ::MessageBox(NULL, "IP_BAD_OPTION","Error",MB_ICONWARNING);
         break;
      case IP_HW_ERROR :
         ::MessageBox(NULL, "IP_HW_ERROR","Error",MB_ICONWARNING);
         break;
      case IP_PACKET_TOO_BIG :
         ::MessageBox(NULL, "IP_PACKET_TOO_BIG","Error",MB_ICONWARNING);
         break;
      case IP_REQ_TIMED_OUT :
         ::MessageBox(NULL, "IP_REQ_TIMED_OUT","Error",MB_ICONWARNING);
         break;
      case IP_BAD_REQ :
         ::MessageBox(NULL, "IP_BAD_REQ","Error",MB_ICONWARNING);
         break;
      case IP_BAD_ROUTE :
         ::MessageBox(NULL, "IP_BAD_ROUTE","Error",MB_ICONWARNING);
         break;
      case IP_TTL_EXPIRED_TRANSIT :
         ::MessageBox(NULL, "IP_TTL_EXPIRED_TRANSIT","Error",MB_ICONWARNING);
         break;
      case IP_TTL_EXPIRED_REASSEM :
         ::MessageBox(NULL, "IP_TTL_EXPIRED_REASSEM","Error",MB_ICONWARNING);
         break;
      case IP_PARAM_PROBLEM :
         ::MessageBox(NULL, "IP_PARAM_PROBLEM","Error",MB_ICONWARNING);
         break;
      case IP_SOURCE_QUENCH :
         ::MessageBox(NULL, "IP_SOURCE_QUENCH","Error",MB_ICONWARNING);
         break;
      case IP_OPTION_TOO_BIG :
         ::MessageBox(NULL, "IP_OPTION_TOO_BIG","Error",MB_ICONWARNING);
         break;
      case IP_BAD_DESTINATION :
         ::MessageBox(NULL, "IP_BAD_DESTINATION","Error",MB_ICONWARNING);
         break;

      default :
         ::MessageBox(NULL, "Error","Error",MB_ICONWARNING);
      }
//**************************************
   return icmpEcho->Status;
   }
pIcmpCloseHandle(hndlFile);
delete [] icmpEcho;
return 0;
}
//---------------------------------------------------------------------------


cping.h
Код

#ifndef CPING_H
#define CPING_H
#define No_Create_Class       100
#define Error_Host            101

//#include "StdAfx.h"
#include <windows.h>
#include <winsock.h>
#include <ipexport.h>

typedef struct tagIPINFO
{
    u_char Ttl;                // Time To Live
    u_char Tos;                // Type Of Service
    u_char IPFlags;      // IP flags
    u_char OptSize;      // Size of options data
    u_char FAR *Options;    // Options data buffer
}IPINFO;

typedef IPINFO* PIPINFO;

typedef struct tagICMPECHO
{
    u_long Source;            // Source address
    u_long Status;            // IP status
    u_long RTTime;            // Round trip time in milliseconds
    u_short DataSize;        // Reply data size
    u_short Reserved;        // Unknown
    void FAR *pData;        // Reply data buffer
    IPINFO    ipInfo;     // Reply options
}ICMPECHO;

typedef ICMPECHO* PICMPECHO;

class CPing
{
public:
    CPing();
    ~CPing();
    int CPing::Ping(char* strHost, DWORD mByte, DWORD TimeOut, DWORD *mSek);
private:
    // ICMP.DLL Export Function Pointers
    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
    BOOL bValid;         // if it doesn't construct properly, it won't be valid
};

#endif


Теперь делаем обработчик на кнопке куда записываем код
Здесь код основной программы:
Код

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "Kod.h"
#include "Cping.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
CPing ping;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner){}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
DWORD p;
AnsiString Otvet;
int bResult = ping.Ping(Edit1->Text.c_str(), 1, 3000, &p);
if (bResult==0)
   {
   Otvet="Ping good ("+IntToStr(p)+"ms)";
   Application->MessageBox(Otvet.c_str() ,"Information",MB_ICONINFORMATION+MB_SYSTEMMODAL);
   }
else
   {
   if (bResult==IP_REQ_TIMED_OUT)
         Application->MessageBox("TimeOut" ,"Information",MB_ICONINFORMATION+MB_SYSTEMMODAL);
   }
}
//---------------------------------------------------------------------------

Автор: bigscorp 12.12.2006, 06:33
а почему не возвращает код ошибки если пробуешь пнуть адрес которого в сетке нету  smile 

Автор: Bima 12.12.2006, 09:49
Смотри внимательно код.
в самом конце обрабатывается условие на таймаут, если туда еще поставишь что нибудь из этой таблицы:
Код

#define IP_STATUS_BASE              11000

#define IP_SUCCESS                  0
#define IP_BUF_TOO_SMALL            (IP_STATUS_BASE + 1)
#define IP_DEST_NET_UNREACHABLE     (IP_STATUS_BASE + 2)
#define IP_DEST_HOST_UNREACHABLE    (IP_STATUS_BASE + 3)
#define IP_DEST_PROT_UNREACHABLE    (IP_STATUS_BASE + 4)
#define IP_DEST_PORT_UNREACHABLE    (IP_STATUS_BASE + 5)
#define IP_NO_RESOURCES             (IP_STATUS_BASE + 6)
#define IP_BAD_OPTION               (IP_STATUS_BASE + 7)
#define IP_HW_ERROR                 (IP_STATUS_BASE + 8)
#define IP_PACKET_TOO_BIG           (IP_STATUS_BASE + 9)
#define IP_REQ_TIMED_OUT            (IP_STATUS_BASE + 10)
#define IP_BAD_REQ                  (IP_STATUS_BASE + 11)
#define IP_BAD_ROUTE                (IP_STATUS_BASE + 12)
#define IP_TTL_EXPIRED_TRANSIT      (IP_STATUS_BASE + 13)
#define IP_TTL_EXPIRED_REASSEM      (IP_STATUS_BASE + 14)
#define IP_PARAM_PROBLEM            (IP_STATUS_BASE + 15)
#define IP_SOURCE_QUENCH            (IP_STATUS_BASE + 16)
#define IP_OPTION_TOO_BIG           (IP_STATUS_BASE + 17)
#define IP_BAD_DESTINATION          (IP_STATUS_BASE + 18)

то будет выдавать и ошибку и все, что ты захочешь.

Автор: bigscorp 13.12.2006, 03:00
факт!! респект Bima ... а не подскажешь, можно ли на основе этой функции создать что-то типа tracert?
в принципе я понял как это сделать ... ттл увеличивать на 1 и будет путь прохождения пакета пока не уткнется в указанный адрес, но не могу ИП получить из icmpEcho

Автор: Bima 13.12.2006, 06:37
Сложно сказать, ничего в голову с ходу не лезет. Сделай новую ветку в форуме, думаю, тебе здесь помогут.

Автор: SergXP 5.5.2008, 15:19
Извеняюсь, что поднимаю старую тему, но у меня такая проблема

Добавил StringGrid, две колонки IP Adress и Ping

Начинаю считывать каждую ячейку с IP Адрессом и получаю пинг, но он отображается не правильно

например

XXX.XXX.XXX.XXX 30ms
YYY.YYY.YYY.YYY 30 ms

ZZZ.ZZZ.ZZZ.ZZZ 180ms
DDD.DDD.DDD.DDD 180 ms

Не понятно, почему происходит запись пинга два раза на разные айпи адреса

Плюс к тому же, я записываю каждый шаг в Memo, и в нем выводятся строки
1
2
3
4
5
6
Выводятся они не быстро, сразу тока нажал, 1, 2 потом думает, 3,4 опять думает и так далее

Вот такой у меня кодик..

Код

void __fastcall TForm1::Button1Click(TObject *Sender)
{
 DWORD p;
AnsiString Otvet;
int x,y;
x=1;
 while (x<=StringGrid1->RowCount-1) {
 &p == "";

 Memo1->Lines->Add(IntToStr(x)+" ");
 int bResult = ping.Ping(StringGrid1->Cells[0][x].c_str(), 5, 1000, &p);
 StringGrid1->Cells[1][x] = IntToStr(p);
 x++;


 }


Но почему то не работает! smile 

Автор: SergXP 7.5.2008, 20:00
 smile  люди! Хелп! smile 

Автор: Bima 8.5.2008, 13:19
Похоже функция вызывается, но параметры остались с прошлого раза.
попробуй в цикле вставь задержку с временем таймаута пинга, если это не поможет будем дальше разбираться

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)