开发者

PHP fsockopen() painfully slow

I'm using fsockopen() to call a number of connections in a list to see the online status of various ip/host and ports ...

<?php
$socket = @fsockopen($row[2], $row[3], $errnum, $errstr, 1);
if ($errnum >= 1) { $status = 'offline'; } else { $status = 'online';}
fclose($socket);

if works, I'm not complaining about that, but I have approximately 15 ip/ports that i'm retrieving in a list (php for() command..). I was wondering if there is a better way to do this? This way is 开发者_StackOverflowVERY slow!?! It is taking about 1-2 minutes for the server to come back with a response for all of them..

Update:

<?php
$socket = @fsockopen("lounge.local", "80", $errnum, $errstr, 30);
if ($errnum >= 1) { $status = 'offline'; } else { $status = 'online'; }
?>

It will display in a list: "ReadyNAS AFP readynas.local:548 online"

I don't know what more I can tell you? It just takes forever to load the collection of results...


From my own experience:

This code:

$sock=fsockopen('www.site.com', 80);

is slower compared to:

$sock=fsockopen(gethostbyname('www.site.com'), 80);

Tested in PHP 5.4. If doing many connections at the same time one could keep host resolution result and re-use it, to further reduce script time execution, for example:

function myfunc_getIP($host) {
   if (isset($GLOBALS['my_cache'][$host])) {
      return $GLOBALS['my_cache'][$host];
   }

   return $GLOBALS['my_cache'][$host]=gethostbyname($host);
}

$sock=fsockopen(myfunc_getIP('www.site.com'), 80);


If you plan to "ping" some URL, I would advise doing it with curl, why? you can use curl to send pings in parallel, have a look at this -> http://www.php.net/manual/en/function.curl-multi-init.php. In a previous project, it was supposed to feed Real Time Data to our server, we used to ping hosts to see if they are alive or not and Curl was the only option that helped us. Its an advice, may not be a right solution for your problem.


The last parameter to fsockopen() is the timeout, set this to a low value to make the script complete faster, like this:

fsockopen('192.168.1.93', 80, $errNo, $errStr, 0.01)


Have you compared the results of fsockopen(servername) versus fsockopen(ip-address)? If the timeout parameter does not change a thing, the problem may be in your name server. If fsockopen with an IP address is faster, you'll have to fix your name server, or add the domains to /etc/hosts file.


I would recommend doing this a bit different. Put this hosts in a table in a database something like:

++++++++++++++++++++++++++++++++++++
| host | port | status | timestamp |
++++++++++++++++++++++++++++++++++++

And move the status checking part in a cron script that you run it once every 5 minutes or how often you want. This script will check the host:port and update status and timestamp for each record and in your page you will just do a db query and show the host, its status and when was last checked (something like: 1minute ago, etc...) This way your page will load fast.


According to the php manual, there's a timeout parameter. Try setting it to a lower value.

Edit: To add to Daniel's answer, nmap might be the best tool to use. Set it up with a cron job to scan and update your records every X minutes. Something like

$ for ip in $(seq 6 8); 
do 
     port_open=$(nmap -oG - -p 80 10.1.0.$ip|grep open|wc -l); 
     echo "10.1.0.$ip:$port_open"; 
done

10.1.0.6:1
10.1.0.7:1
10.1.0.8:0


I had an issue where fsockopen requests were slow, but wget was really snappy. In my case, it was happening because the hostname had both an ipv4 and ipv6 address, but ipv6 was down. So it took 20 or so seconds on each request for the ipv6 to time out.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜