Router an Pingen



  • Hallo,

    schau dich hier mal um, unter Netzwerk findest du genau was du brauchst.

    http://www.bytesandmore.de/rad/cpp/main/snip_cnt.htm

    Gruß
    Mikel



  • hey danke, das hilft mir schon ein grosses stück weiter.
    jetzt muss i den code den i da gefunden hab für mich einstellen
    und das kann bestimmt noch dauern.
    wenn i noch probs hab dann meld i mich wieder.

    bye
    Haudegen



  • so, das erste problem is da,

    wie kann man prozeduren aufrufen?

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    PingHost("192.168.0.42",RichEdit1 -> Lines);
    }

    also da soll es rein aber ich weis es nicht genau.



  • hast du die Funktion in der Header Datei oder vor der main mit einer Vorwärts Deklaration oder ähnliches bekannt gemacht ?



  • äh, ich poste mal den ganzen quellcode

    //---------------------------------------------------------------------------
    #include <vcl.h>
    #include <conio.h>
    #include <windows.h>
    #pragma hdrstop
    #include <winsock.h>
    #include "ping.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    
    // Definition der IP-Optionenstruktur
    TStrings* pStrings;
    TForm1* Form1;
    
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {}
    typedef struct tagIPINFO
    {
      AnsiString slAddress;
      BYTE bTimeToLive;    // Time To Live
      BYTE bTypeOfService; // Type Of Service
      BYTE bIpFlags;       // IP-Flags
      BYTE OptSize;        // Grösse der Options Data Buffers
      BYTE FAR *Options;   // Zeiger auf Options Data Buffer
    } IPINFO, *PIPINFO;
    
    // Definition der ICMP-Echo Antwortstruktur
    typedef struct tagICMPECHO
    {
      AnsiString slAddress;
      DWORD dwSource;     // Zieladresse
      DWORD dwStatus;     // IP-Status
      DWORD dwRTTime;     // Round Trip Time in Millisekunden
      WORD  wDataSize;    // Grösse des Antwort-Buffers
      WORD  wReserved;
      void FAR *pData;    // Zeiger auf die Antwort-Daten
      IPINFO ipInfo;      // Antwort-Optionen
    } ICMPECHO, *PICMPECHO;
    
    // Zeiger auf die Funktionen aus der ICMP.DLL deklarieren:
    typedef HANDLE (WINAPI *PF_CMPCREATEFILE)(VOID);
    typedef BOOL   (WINAPI *PF_ICMPCLOSEHANDLE)(HANDLE);
    typedef DWORD  (WINAPI *PF_ICMPSENDECHO)(HANDLE,DWORD,LPVOID,WORD,
                                             PIPINFO,LPVOID,DWORD,DWORD);
    
    //---------------------------------------------------------------------------
    // Funktion PingHost() sendet ein IMCP-Echo Request (Ping) an den Rechner
    // mit der im Parameter slAddress übergebenen Adresse (oder Namen)
    //---------------------------------------------------------------------------
    // Übergabeparameter:
    //
    // AnsiString slAddress : IP-Adresse oder Name des Zielrechners
    // TStrings* pStrings   : Zeiger auf eine TStrings-Instanz für die
    //                        Ausgabe von Statusmeldungen
    //---------------------------------------------------------------------------
    // Rückgabewert:        : Round Trip Time des Echo Request (die Zeit von dem
    //                        Anfragezeitpunkt bis zum Empfang der Antwort)
    //                        in Millisekunden bei erfolgreicher Ausführung oder
    //                        -1 beim Auftreten von Fehlern
    //---------------------------------------------------------------------------
    // Beispielaufrufe:
    //
    // int ilTripTime = PingHost("xxx.xxx.xxx.xxx", Memo1->Lines);
    // int ilTripTime = PingHost("test_host", NULL);
    //---------------------------------------------------------------------------
    int PingHost(AnsiString slAddress ,TStrings* pStrings)
    {
      // Stringsliste leeren:
      if(pStrings) pStrings->Clear();
    
      // ICMP.DLL laden:
      HANDLE hIcmp = LoadLibrary("ICMP.DLL");
      if(hIcmp == NULL)
      {
        if(pStrings) pStrings->Add("Could not load ICMP.DLL");
        return -1;
      }
    
      // Zeiger auf die Funktionen besorgen:
      PF_CMPCREATEFILE pfIcmpCreateFile = (PF_CMPCREATEFILE)
        GetProcAddress(hIcmp, "IcmpCreateFile");
      PF_ICMPCLOSEHANDLE pfIcmpCloseHandle = (PF_ICMPCLOSEHANDLE)
        GetProcAddress(hIcmp,"IcmpCloseHandle");
      PF_ICMPSENDECHO pfIcmpSendEcho = (PF_ICMPSENDECHO)
        GetProcAddress(hIcmp,"IcmpSendEcho");
    
      // Funktionszeiger prüfen:
      if (pfIcmpCreateFile == NULL || pfIcmpCloseHandle == NULL ||
        pfIcmpSendEcho == NULL)
      {
        if(pStrings) pStrings->Add("Error getting ICMP proc address");
        FreeLibrary(hIcmp);
        return -1;
      }
    
      // WinSock initialisieren
      WSADATA wsaData;
      int ilRetVal = WSAStartup(0x0101, &wsaData );
      if(ilRetVal)
      {
        if(pStrings)
          pStrings->Add("Winsock-Initialsierungsfehler: " + IntToStr(ilRetVal));
        WSACleanup();
        FreeLibrary(hIcmp);
        return -1;
      }
      // Check WinSock version
      if(0x0101 != wsaData.wVersion)
      {
        if(pStrings)
          pStrings->Add("Fehler: Winsock Version 1.1 oder höher nicht vorhanden !");
        WSACleanup();
        FreeLibrary(hIcmp);
        return -1;
      }
    
      // Prüfen, ob es sich bei der Zieladresse um IP-Adresse handelt und
      // ggf. den die Adresse zum Namen ermitteln:
      struct in_addr iaDest;  // Struktur für die Internet-Adresse
      iaDest.s_addr = inet_addr(slAddress.c_str());
      LPHOSTENT pHost;  // Zeiger auf die Host Entry Struktur
      if (iaDest.s_addr == INADDR_NONE) pHost = gethostbyname(slAddress.c_str());
      else pHost = gethostbyaddr((BYTE *)&iaDest, sizeof(struct in_addr), AF_INET);
      if(pHost == NULL)
      {
        if(pStrings)
          pStrings->Add("Fehler: Adresse " + slAddress + " wurde nicht gefunden !");
        WSACleanup();
        FreeLibrary(hIcmp);
        return -1;
      }
    
      if(pStrings)
        pStrings->Add("Ping an " + AnsiString(pHost->h_name) + "[" +
          AnsiString(inet_ntoa((*(LPIN_ADDR)pHost->h_addr_list[0]))) + "]");
    
      // IP-Adresse kopieren
      DWORD* pAddress = (DWORD*)(*pHost->h_addr_list);
    
      // ICMP Echo Request Handle besorgen:
      HANDLE hIcmpFile = pfIcmpCreateFile();
    
      ICMPECHO icmpEcho;      // ICMP-Echo Antwortbuffer
      IPINFO ipInfo;          // IP-Optionenstruktur
    
      int ilTimeSum = 0;      // Summe der Round Trip Time-Daten
      int ilCount   = 0;      // Anzahl der Round Trip Time-Daten
    
      for (int ilPingNo = 0; ilPingNo < 3; ilPingNo++)
      {
        // Default-Werte festlegen:
        ::ZeroMemory(&ipInfo, sizeof(ipInfo));
        ipInfo.bTimeToLive = 255;
        // ICMP Echo anfordern:
        pfIcmpSendEcho(hIcmpFile,   // Handle von IcmpCreateFile()
                       *pAddress,   // Ziel-IP Addresse
                        NULL,       // Zeiger auf den Buffer mit den
                                    // zu sendenden Daten
                        0,          // Buffergrösse in Bytes
                        &ipInfo,    // Request-Optionen
                        &icmpEcho,  // Antwort-Buffer
                        sizeof(struct tagICMPECHO), // Buffergrösse
                        5000);      // Max. Wartezeit in Millisekunden
    
        // Ergebnisse anzeigen:
        iaDest.s_addr = icmpEcho.dwSource;
        if(pStrings)
        {
          AnsiString slMessage = "Antwort von "+AnsiString(
            inet_ntoa(iaDest))+ ": Zeit=" + IntToStr(icmpEcho.dwRTTime) +
            " ms, Time to Live=" + IntToStr(icmpEcho.ipInfo.bTimeToLive) + " ms";
          pStrings->Add(slMessage);
        }
        // falls Fehler aufgetreten:
        if(icmpEcho.dwStatus)
        {
          if(pStrings)
            pStrings->Add("Fehler: IcmpEcho-Status=" + IntToStr(icmpEcho.dwStatus));
          break;
        }
        ilTimeSum += icmpEcho.dwRTTime;
        ilCount++;
        if(ilPingNo < 2) Sleep(200);
      }
    
      // Echo-Request File Handle schliessen:
      pfIcmpCloseHandle(hIcmpFile);
      // ICMP.DLL freigeben:
      FreeLibrary(hIcmp);
      // Winsock schliessen:
      WSACleanup();
    
      // Den Mittelwert aller Round Trip Times zurückgeben:
      return ilRetVal = ilCount ? ilTimeSum/ilCount : -1;
    }
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    PingHost("192.168.0.42",RichEdit1 -> Lines);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
    Close();
    }
    //---------------------------------------------------------------------------
    

    ähm hoffe mal, da blickt einer durch



  • also wenn du das genau so hast wie da beschrieben ... dann muss ich dir gratulieren das funktioniert einwandfrei ... Mfg 🙄



  • hmm... cool danke aber das mit dem RichEdit funzt nicht, bekomme da keine ausgabe. kann ich das auch mit ner ListBox machen?



  • Haudegen auch das mit der Richedit komponente geht nur vermutlich gibt es diese Ip Adresse in deinem Netzwerk nicht und deswegen solltest du eventuell 15 sek warten solang hats bei mir gedauert bis die Meldung "Adresse BLA BLA wurde nicht gefunden " in der Richedit Komponente aufgetaucht ist

    MfG 😉

    Geduld ist manchmal auch in der Programmierung nicht schlecht 🙂



  • Macht euch doch nicht lächerlich mit dem WinAPI-Mörder-Ping. 😉
    Im BCB6 gibt's unter Indy eine ICMP-Komponente, damit erledigst du das sozusagen im Handumdrehen.



  • hmm... tut sich nix, haben das jetzt knap 8 minuten laufen lassen aber kam nix.
    andere frage, kann ich das auch mit ner listbox machen?



  • wie funktioniert das mit dem indy, muss ich da noch was nachinstallieren oder geht das mit den "dingern" von bcb6?


Anmelden zum Antworten