Laurens Stoetzel: Mit Ping eine Domain auf Existenz überprüfen?

Hallo!

Ich brauche dringend Hilfe mit meinem Script. In einer MySQL DB sind mehrere Server gespeichert und das Script soll sie nun alle anpingen um zu prüfen welche dieser Domains online ist.

Bisher sieht mein Script so aus:

//Beispiel-Werte
//$link = "www.mydomain.com";
//$path = "/index.php";

function Ping($link, $path)
{
 if(FileExists($link . $path)=="1") {
     echo "File existiert";
  $churl = @fsockopen("http://" . $link, 80, $errno, $errstr, 3);
  if (!$churl) {
   $meldung = "0";
  } else {
   $meldung = "1";
  }
  return $meldung;
 }
 else {
  return FileExists($link . $path);
 }
}
function FileExists($link)
{
 @$fid = fsockopen("http://" . $link, 80, $errno, $errstr, 30);
 echo $fid;
 if(!$fid) { return $errstr; }
 else { return 1; fclose($fid); }
}

Leider funktioniert das so nicht und als Endergebnis kriege ich alle Server als Offline angezeigt. Kann mir jemand helfen?

Ich möchte NICHT mit der system() Funktion arbeiten, weil mir dieser Weg zu "dreckig" erscheint, von der anschließenden Auswertung ganz abgesehen.

Vielen Dank
Laurens Stoetzel

  1. Hallo,

    [...]
      $churl = @fsockopen("http://" . $link, 80, $errno, $errstr, 3);
    [...]
    @$fid = fsockopen("http://" . $link, 80, $errno, $errstr, 30);

    Ney, ney, ney. So geht das nicht. fsockopen() oeffnet einen socket und erwartet
    einen *Domainnamen*, keine URL.

    Gruesse,
     CK

    --
    http://sf.net/projects/libtemplate/
    http://sf.net/projects/mod-gzip/

    1. Ney, ney, ney. So geht das nicht. fsockopen() oeffnet einen
      socket und erwartet einen *Domainnamen*, keine URL.

      Ok, habe mein Script so abgewandelt und es scheint zu erkennen ob der Server erreichbar ist:

      function Ping($link, $path)
      {
       $link = correcturl($link);
       if(FileExists($link)=="1") {
        $churl = @fsockopen($link, 80, $errno, $errstr, 30);
        if (!$churl) {
         $meldung = "0";
        } else {
         $meldung = "1";
         fclose($churl);
        }
        return $meldung;
       }
       else {
        return FileExists($link . $path);
       }
      }
      function correcturl($link){
        return str_replace("http://","",strtolower($link));
      }
      function FileExists($link)
      {
       @$fid = fsockopen($link, 80, $errno, $errstr, 30);
       echo $fid;
       if(!$fid) { return $errstr; }
       else { fclose($fid); return 1; }
      }

      Allerdings überprüft nun die Funktion FileExists (noch) nicht ob die Datei existiert, ich möchte aber auch nicht die gesamte Datei runterladen, die Header reichen ja um zu sehen ob die Datei existiert oder nicht.
      Kannst du mir da noch helfen?

      Vielen Dank
      Laurens Stoetzel

      1. Hallo,

        $churl = @fsockopen($link, 80, $errno, $errstr, 30);
        [...]
        @$fid = fsockopen($link, 80, $errno, $errstr, 30);

        Ich wuerde nur einmal eine Verbindung aufmachen. Der TCP/IP-Verbindungsaufbau ist
        sehr teuer (4 Pakete nur fuer den Aufbau).

        Allerdings überprüft nun die Funktion FileExists (noch) nicht ob die Datei
        existiert, ich möchte aber auch nicht die gesamte Datei runterladen, die
        Header reichen ja um zu sehen ob die Datei existiert oder nicht.
        Kannst du mir da noch helfen?

        RFC 2616 (http://www.rfc-editor.org/cgi-bin/rfcdoctype.pl?loc=RFC&letsgo=2616&type=ftp&file_format=txt) hilft: HEAD ist die Methode, die du suchst.

        Gruesse,
         CK

        --
        http://sf.net/projects/libtemplate/
        http://sf.net/projects/mod-gzip/

        1. HEAD ist die Methode, die du suchst.

          Ok, ich habs damit versucht:

          function FileExists($flink, $fpath)
          {
           $fid = @fsockopen($flink, 80, $errno, $errstr, 1);
           if($fid) {
            fputs ($fid, "HEAD " . $fpath . " HTTP/1.0");
                   while(!feof($fid)){
                            echo fgets ($fid,128);
                          }
            fclose ($fid);
           }
          }

          Aber damit bekomm ich immer einen Timeout (Maximum execution time exceeded)...

          Vielen Dank
          Laurens Stoetzel

          1. Hallo,

            function FileExists($flink, $fpath)
            {
            $fid = @fsockopen($flink, 80, $errno, $errstr, 1);
            if($fid) {
              fputs ($fid, "HEAD " . $fpath . " HTTP/1.0");

            fputs($fid,'HEAD '.$fpath." HTTP/1.1\015\012Connection: close\015\012Host: $host\015\012\015\012");

            Aber damit bekomm ich immer einen Timeout (Maximum execution time exceeded)...

            Kein Wunder: jede Zeile muss mit einem Zeilenumbruch (definiert als <CR><LF>, also \015\012)
            beendet werden. Um anzuzeigen, dass der Header zuende ist, muss eine Leerzeile gesendet
            werden.

            Gruesse,
             CK

            1. Kein Wunder: jede Zeile muss mit einem Zeilenumbruch (definiert als <CR><LF>, also \015\012)
              beendet werden. Um anzuzeigen, dass der Header zuende ist, muss eine Leerzeile gesendet
              werden.

              Verdammt du bist gut :)

              Es funktioniert, vielen Dank!

              Laurens Stoetzel

              1. hmmm wohl doch net: ("Host: server", da $host bei mir nicht funktionierte)

                function FileExists($flink, $fpath)
                {
                 $dummy = "";
                 $fid = @fsockopen($flink, 80, $errno, $errstr, 1);
                 if($fid) {
                  fputs($fid,'HEAD '.$fpath." HTTP/1.1\015\012Connection: close\015\012Host: fmo-server\015\012\015\012");
                     while(!feof($fid)) {
                   $dummy += fgets ($fid,128);
                  }
                  fclose ($fid);
                  if($dummy) { return 1; }
                  else { return 0; }
                 }
                 else {
                  return 0;
                 }
                }

                Leider ist $dummy immer leer, bzw. ich scheine keine Header zu erhalten, der Link ist allerdings richtig und funktioniert.

                Vielen Dank
                Laurens Stoetzel

                1. Moin,

                  hmmm wohl doch net: ("Host: server", da $host bei mir nicht funktionierte)

                  Doch, der Host:-Header sollte immer den Namen des Hosts enthalten den du ansprechen willst. Wenn du nämlich auf virtual hosts triffst (also mehrere Hostnamen hinter einer IP-Addresse, extrem verbreitet heutzutage) entscheidet der Server aufgrund dieses Hostnamens welchen host du meinst. Selbstverfreilich musst du den Namen der Variable die den Hostnamen enthält für $host einsetzen.

                  fputs($fid,'HEAD '.$fpath." HTTP/1.1\015\012Connection: close\015\012Host: fmo-server\015\012\015\012");

                  Hinweis für später: Wenn du dich mal entscheiden solltest auf diese Weise den Inhalt der Seite holen zu wollen, möchtest du wirklich 1.0 statt 1.1 senden, sonst musst du Transfer-Encoding: Chunked verstehen können.

                  $dummy += fgets ($fid,128);

                  Strings verbindet man in PHP mit einem ., ich bin verwundert dass er dir diese Zeile nicht um die Ohren gehauen hat. Wahrscheinlich hat er kurzerhand deinen String nach Integer konvertiert, da du ihn ja darum gebeten hast zwei Zahlen zu addieren.

                  if($dummy) { return 1; }

                  An dieser Stelle solltest du den Status-Code der Antwort prüfen. 200 bedeutet alles OK, 404 Datei nicht gefunden usw. Findest du im bereits verlinkten RFC.

                  Weitere Beispiele wie man HTTP 'zu Fuß' mit PHP macht finden sich übrigens im Archiv und in den Userkommentaren der Doku auf php.net.

                  --
                  Henryk Plötz
                  Grüße aus Berlin

                  1. Der Host:-Header sollte immer den Namen des Hosts enthalten den du ansprechen willst.

                    Jo, hatte ich auch ausprobiert, funktionierte nicht, deshalb hatte ich dem Host Eintrag keine große Bedeutung zugemessen... :)

                    Hinweis für später: Wenn du dich mal entscheiden solltest auf
                    diese Weise den Inhalt der Seite holen zu wollen, möchtest du
                    wirklich 1.0 statt 1.1 senden, sonst musst du Transfer-Encoding:
                    Chunked verstehen können.

                    Ok, hab das umgestellt.

                    Strings verbindet man in PHP mit einem ., ich bin verwundert dass
                    er dir diese Zeile nicht um die Ohren gehauen hat. Wahrscheinlich
                    hat er kurzerhand deinen String nach Integer konvertiert, da du
                    ihn ja darum gebeten hast zwei Zahlen zu addieren.

                    *räusper* ja, ich bin ja noch nicht so lange mit PHP zugange...sry :)

                    if($dummy) { return 1; }
                    An dieser Stelle solltest du den Status-Code der Antwort prüfen. 200 bedeutet alles OK, 404 Datei nicht gefunden usw. Findest du im bereits verlinkten RFC.

                    Das wollte ich noch machen, hab das aber bewusst erst rausgelassen, da $dummy ja eh immer leer war, trotzdem nochmal danke für den Hinweis.

                    Vielen Dank
                    Laurens Stoetzel

                    1. Ach ja vergaß: Es funktioniert jetzt... :D

                      Nochmal vielen Dank
                      Laurens Stoetzel