Czy istnieje sposób na otrzymanie nazwy hosta z adresu IP, ograniczając przy tym czas połączenia (nie chodzi mi o czas wykonania skryptu)?
Funkcja gethostbyaddr byłaby w porządku, gdyby zwracała cokolwiek, w przypadku timeoutu. Niestety tak nie jest i kiedy host nie odpowiada, skrypt będzie mielił aż do przekroczenia maksymalnego czasu wykonania skryptu.
Już w samych komentarzach w manualu, przy funkcji gethostbyaddr natrafiłem na taki oto skrypt:
function gethostbyaddr_timeout($ip, $dns, $timeout=1000) { // random transaction number (for routers etc to get the reply back) // trim it to 2 bytes // request header $data .= "\1\0\0\1\0\0\0\0\0\0"; // split IP up // error checking // there is probably a better way to do this bit... // loop through each segment for ($x=3; $x>=0; $x--) { // needs a byte to indicate the length of each segment of the request { case 1: // 1 byte long segment $data .= "\1"; break; case 2: // 2 byte long segment $data .= "\2"; break; case 3: // 3 byte long segment $data .= "\3"; break; default: // segment is too big, invalid IP return "INVALID"; } // and the segment itself $data .= $bits[$x]; } // and the final bit of the request $data .= "\7in-addr\4arpa\0\0\x0C\0\1"; // create UDP socket // send our request (and store request size so we can cheat later) // hope we get a reply if ($response == "") return $ip; // find the response type if ($type[1] == 0x0C00) // answer { // set up our variables $host=""; $len = 0; // set our pointer at the beginning of the hostname // uses the request size from earlier rather than work it out $position=$requestsize+12; // reconstruct hostname do { // get segment size // null terminated string, so length 0 = finished if ($len[1] == 0) // return the hostname, without the trailing . // add segment to our host // move pointer on to the next segment $position += $len[1] + 1; } while ($len != 0); // error - return the hostname we constructed (without the . on the end) return $ip; } return $ip; }
Nieco zmodyfikowany kod znalazłem na https://www.askapache.com/php/php-fsockopen-dns-udp/ . Niestety, oba mają pewną wadę.
Większość hostów wyświetla poprawnie. Jeśli nie uda się połączyć z adresem, funkcja zwróci IP, który został podany. Kiedy host nie odpowiada, skrypt zwraca host reverse DNS, w postaci "<ip>.in-addr.arpa".
Niestety, niekiedy skrypt ten zwraca niezrozumiałe dla mnie ciągi znaków, przy czym przy każdej próbie ciągi są inne.
Kod
String (126) "..65196144182193in-addrarpa ..7196144182193in-addrarpa "
String (80) "..33196144182193in-addrarpa .rpa "
String (137) "..53196144182193in-addrarpa .93in-addrarpa .144182193in-addrarpa "
String (31) "..-addrarpa /"
String (80) "..33196144182193in-addrarpa .rpa "
String (137) "..53196144182193in-addrarpa .93in-addrarpa .144182193in-addrarpa "
String (31) "..-addrarpa /"
Prześledziłem już parę stron google i nie znalazłem rozwiązania tego problemu. Ktoś spotkał się z podobnym?