开发者

PHP Sockets, any way to speed this up

I'm writing a small script to see if certain ports on certain devices are in use or are open. My code is:

for($c=1;$c<=16;$c++){
  echo "<tr><td>Pod " . $c . "</td>";
  for ($d=5000;$d<=5010;$d++){
    $tmp=fsockopen("10.0.0." . $c,$d,$erstr, $errno, 1);
    if($tmp){
      echo "<td class='o'>OPEN</td>";
      fclose($tmp);
    }
    else{
      echo "<td class='u'>IN USE</td>";
    }
  }
    ob_flush();
    flush();
  echo "</开发者_运维技巧tr>\n";
}
echo "</table>";

Obviously this is a lot of connections, and currently it's taking about ten seconds to run. I was wondering if there's any way I can get this to be a little bit faster? Thanks for the help!


One way to speed this up tremendously is to get asynchronous. Right now if one of the hosts is slow, it will slow down the entire pipeline because you're doing one right after another. PHP doesn't really have an event-based AIO (select), or even threading. It does, however, have fork in a linux environment. The following example hasn't been tested, but is a general idea for how to do asynchronous IO in php:

 <?php

 $childrenArr = array();
 $childrenLeft = array();

 for($c=1;$c<=16;$c++){
   for ($d=5000;$d<=5010;$d++){
     $pid = pcntl_fork();
     if ($pid == -1) {
         die("Could not fork");
     } else if ($pid) {
         $childrenArr[$pid] = array($c, $d);
         $childrenLeft[$pid] = 1;
     } else {
         $tmp=fsockopen("10.0.0." . $c,$d,$erstr, $errno, 1);
         exit(($tmp) ? 1 : 0);
     }
   }
 }

 $results = array();

 while (count($childrenLeft) > 0) {
      $oldPid = pcntl_waitpid(-1, $status, WNOHANG);
      if (pcntl_wifexited($status )) {
              unset($childrenLeft[$oldPid]);
              list($c, $d) = $childrenArr[$oldPid];
              $results[$c . "_" . $d] = pcntl_wexitstatus($status);
      }
      usleep(100);
 }

 for($c=1;$c<=16;$c++){
   echo "<tr><td>Pod " . $c . "</td>";
   for ($d=5000;$d<=5010;$d++){
     if ($results[$c . "_" . $d]) {
       echo "<td class='o'>OPEN</td>";
     }
     else {
       echo "<td class='u'>IN USE</td>";
     }
   }
   ob_flush();
   flush();
   echo "</tr>\n";
 }
 echo "</table>";


If a given port is not listening/accepting you will suffer all the TCP timeouts on the SYN packet re-transmissions sent out during the three-way handshake. This is the design of the TCP - we can't change that.

One thing I can recommend is switching from streams to the socket functions and trying non-blocking connect - create your 160 sockets, set them to non-blocking, initiate all connections, wait on them in select with a decreasing timeout, flag the ones that return readable. Do that in a loop until you spent, say, a whole second. Now you get a list of open TCP host/port pairs, and a list of likely closed ones, and you spent a fixed amount of time.

Disclaimer: I never do networking in PHP, so this might be totally useless.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜