PHP套接字,任何提高速度的方法

时间:2010-10-27 18:03:05

标签: php sockets optimization

我正在编写一个小脚本,以查看某些设备上的某些端口是否正在使用或是否已打开。我的代码是:

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>";

显然这是很多连接,目前运行大约需要十秒钟。我想知道是否有任何方法可以让它更快一点?谢谢你的帮助!

2 个答案:

答案 0 :(得分:2)

如果给定端口没有侦听/接受,您将在three-way handshake期间发送的SYN数据包重新传输中遭受所有TCP超时。这是TCP的设计 - 我们无法改变它。

我可以推荐的一件事是从流切换到socket functions并尝试非阻塞连接 - 创建160个套接字,将它们设置为non-blocking,启动所有connect个离子,等待对于select中的超时减少,标记返回可读的那些。一直循环,直到你花了一整秒钟。现在,您将获得一个打开的TCP主机/端口对列表,以及可能已关闭的列表,并且您花费了固定的时间。

免责声明:我从不在PHP中建立网络,所以这可能完全没用。

答案 1 :(得分:2)

极速提高速度的一种方法是异步。现在,如果其中一个主机速度很慢,它会减慢整个管道的速度,因为你正在做一个接一个。 PHP实际上没有基于事件的AIO(选择),甚至是线程。但是,它确实在Linux环境中有分叉。以下示例尚未经过测试,但是关于如何在php中执行异步IO的一般概念:

 <?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>";