Fsockopen - test otvoreného portu – PHP – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Fsockopen - test otvoreného portu – PHP – Fórum – Programujte.comFsockopen - test otvoreného portu – PHP – Fórum – Programujte.com

 

Prog.0
Věrný člen
17. 9. 2007   #1
-
0
-

Potrebujem [podtrzene]rýchlo[/podtrzene] otestovať či sú porty na daných ip otvorené. Zatiaľ cyklicky volám cca toto (iné riešenie som ani inde nenašiel):

$timeout = 2;  // 2 sec na otestovanie

$status = ST_UNKNOWN;

if ($f = @fsockopen($ip,$port,$errno,$errstr,$timeout))
{
fclose($f); $status = ST_ONLINE; // zapnuty
} else $status = ST_OFFLINE; // vypnuty


Potrebujem aby to bolo rýchlejšie (zisťujem stav asi 10 ip naraz). Ak je host online => no problem, ak je host offline->stojí to 2 sec - čo je veľa. Keď zmením timeout na 0.5s, niekedy ani nestihne zisťiť že je server online. To mi však vôbec nevadí, chcem vtedy vedieť, že ide o timeout - nestihol => $status = ST_UNKNOWN (neznámy); alebo je port naozaj closed => $status = ST_OFFLINE;

Pozeral som ne tie chybové hlásenia $errno, $errstr, ale stále vracia to isté: 10060 - Nestihol v danom intervale odpovedať.
Do sietí sa až tak nevyznám, ale myslím že ak je host online, a daný port ma offline, tak by mohol odpovedať, že port je closed a tak už viac nemusím čakať. Alebo zisťovanie offline stavu naozaj funguje iba na základe toho, že server neodpovie do $timeout času ?

Rýchly test viacerých host:port - Napadá niekoho nejaké iné riešenie ?

Nahlásit jako SPAM
IP: ...–
Prog.
Prog.0
Věrný člen
18. 9. 2007   #2
-
0
-

Jou, takže existuje spôsob s priamym použitím socketov. http://www.php.net/manual/en/ref.sockets.php Tie umožňujú socket_set_nonblock, takže môžem odpáliť všetky testy naraz. Problém je, že to na mojom PHP nebeží (nutné zapnúť podporu socketov pri kompilácii PHP). Ide hlavne o to, že to robím ako open projekt, tak chcem minimum závislostí, takže ani nechecm zapínať.

Tak som začal rozmýšlať, ako to urobiť multi-threadovo, tak, aby sa tie testy mohli vykonávať naraz aj s použitím fsockopen(). PHP s vláknami asi veľmi nevie (aspoň som nenašiel), tak som to riešil volaním externých scriptov.

script portcheck.php:

#!/usr/bin/php

<?php

if ($f=@fsockopen($argv[1],$argv[2],$errno,$errstr,$argv[3]))
{
fclose($f);
exit("ONLINE\n");
}
exit("OFFLINE\n");

?>


A tento script volám fciou proc_open www.php.net/proc_open toľko krát, koľko mám serverov. Odovzdávam parametre [server, port, timeout]. Scripty bežia paralelne, čiže za 2 sec stihne otestovať asi 20 serverov. Nevýhoda je že sa to pre každé vlákno musí interpretovať odznova, čo si myslím že dosť spomaľuje. Výsledný čas je však neporovnateľne kratší ako pri sériovom testovaní.

Stále to však nieje také riešenie ako by som chcel. Najviac sa mi pozdáva použitie Socket Functions v non-blocking móde, ktoré bude každopádne najrýchlejšie. Škoda že tieto funkcie nie sú s php štandardne skompilované.

Nahlásit jako SPAM
IP: ...–
Prog.
Prog.0
Věrný člen
19. 9. 2007   #3
-
0
-

Uf, tak som rád, že nie som sám, kto to riešil... tretí deň googlenia priniesol svoje ovocie :-)

http://netevil.org/blog/2005/may/guru-multiplexing

[podtrzene]Využíva[/podtrzene]: stream_socket_client s flagom STREAM_CLIENT_ASYNC_CONNECT a stream_select, čo umožnuje pracovať so stream-ami rovnako ako so socketmi, aj keď sockety nie su dostupné. Dokonca sa to dá jednoducho skombinovať (potom bude vyžadovať PHP5 alebo PHP4+ext/sockets).

www.php.net/stream_socket_client
http://www.php.net/stream_select


EDIT:

Takže tu je vysledná funkcia, ktora testuje dostupnosť viacerých služieb naraz (vyžaduje PHP5):

Vstypy:
$services = pole stringov "host:port"
$timeout = čas v sekundách (aj float)

Výstup
= pole(rovnaké indexy ako $services) s hodnotami:
null - chyba
false - nedostupný (timeout)
true - zapnuty

  function check_services($services,$timeout=1)

{

$time_start = microtime(true);

$socket = Array();
$status = Array();
$error = Array();

foreach ($services as $id => $service)
{
$status[$id] = null;
if($s = stream_socket_client($service, $errno, $errstr, $timeout, STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT)) $socket[$id] = $s;
}

while(count($socket))
{
$write = $socket; $e = null;
if (($timeout_remaining=$time_start+$timeout-microtime(true))>0 && stream_select($e, $write, $e, $timeout_remaining))
{
foreach($write as $w)
{
$id = array_search($w, $socket);
$status[$id] = true;
fclose($w);
unset($socket[$id]);
}
} else {
foreach($socket as $id => $s)
{
$status[$id] = false;
fclose($socket[$id]);
unset($socket[$id]);
}
break;
}
}
return $status;
}


Použitie:
  $services = Array(

'localhost:21',
'localhost:25',
'localhost:80',
'localhost:110',
'programujte.com:80');

print_r(check_services($services));

Nahlásit jako SPAM
IP: ...–
Prog.
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 9 hostů

Podobná vlákna

Udrzovanie otvoreneho pripojenia — založil peter ciz

Fsockopen a pop3 — založil tonez

Hledám freehostig (PHP+FSockOpen+SSL) — založil Anonymní uživatel

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý