我正在编写一个小脚本,以查看某些设备上的某些端口是否正在使用或是否已打开。我的代码是:
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>";
显然这是很多连接,目前运行大约需要十秒钟。我想知道是否有任何方法可以让它更快一点?谢谢你的帮助!
答案 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>";