Router an Pingen



  • Ein grobes Hallo

    also, ich hab vor n program mit Borland c++ builder 6 zu erstellen, das meinen router anpingt und bei nicht erreichen des routers ne messagebox ausspuckt.
    mein problem is es, ich will die ping sache in nem kleinen fenster in dem program dargestellt haben. so mit zeit und was es da so gemacht hat. so wie eine "log" datei, als beispiel fällt mir da jetzt nur emule ein, da steht doch auch wann er mit nem server verbindet und auf welchem er verbindet und und und.
    für mein prog wollte ich ne scrollbox verwenden, für was anderes bin ich natürlich offen.

    ich hoffe das war nicht zu kompliziert ausgedrückt



  • Was willst du jetzt genau wissen?
    Für die Zeit gibts nen TDateTime.. und das Log kannst du in eine Textdatei schreiben.
    Oder brauchst du sonstwas als Info?



  • ich will das prog nur mit einem fenster machen
    die log datei soll dort in dem fenster angezeigt werden

    |--------------------|
    |                    |
    | |---------------|  |
    | |   log-datei   |  |
    | |               |  |
    | |---------------|  |
    |                    |
    |  Button1 Button2   |
    |--------------------|
    

    so soll es grob dann aussehen

    Edit:
    Code-Tags benutzen, dann klappt's auch mit den Bildern. 😉

    [ Dieser Beitrag wurde am 02.07.2003 um 23:06 Uhr von Jansen editiert. ]



  • hmm... shit, is a bisserl unglücklich geworden, hoffe mal ihr könnt es euch mit viel fantasie vorstellen. 😃



  • Nö. Also da gibts natürlich verschieden Wege. Zum GUI-Design sag ich mal gar nix, das bekommst du schon gebacken, ne Listbox od. so was ist ja easy. Musst dich halt in die VCL einarbeiten. Den Ping würde ich entweder über die Winsock C-Programmierung machen (a la C-Worker) oder mit den VCL-Eigenen Komponenten Siehe aber auch FAQ!!!!!!!!!!!!!!!!!!!)
    Hoffe du stellst dir nicht vor, das eine DOS-Box in deinem Programm "drinn" abläuft... 😉

    viele Grüße
    dose



  • nee, bis jetzt hatte ich nur diese standart ping von windows, das weis ich ja das es nicht möglich ist das dos fenster bei mir zu integrieren.
    jedenfalls werde ich deine tips mal gleich testen.



  • 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