在PHP中打开异步套接字
我正在用PHP编写一个支持小范围(例如端口21-25)的端口扫描程序。要扫描的端口和IP通过AJAX发送到服务器,然后PHP尝试在每个端口上打开一个套接字。如果成功,则端口打开;如果超时,则端口关闭 目前,尽管为端口21-25同时发送所有AJAX请求,但每个套接字只有在最后一个套接字关闭后才会打开。因此,检查端口21,关闭插座,然后检查端口22,依此类推。我想要的是同时检查所有端口,因此我将同时打开几个套接字 我试过:在PHP中打开异步套接字,php,sockets,asynchronous,Php,Sockets,Asynchronous,我正在用PHP编写一个支持小范围(例如端口21-25)的端口扫描程序。要扫描的端口和IP通过AJAX发送到服务器,然后PHP尝试在每个端口上打开一个套接字。如果成功,则端口打开;如果超时,则端口关闭 目前,尽管为端口21-25同时发送所有AJAX请求,但每个套接字只有在最后一个套接字关闭后才会打开。因此,检查端口21,关闭插座,然后检查端口22,依此类推。我想要的是同时检查所有端口,因此我将同时打开几个套接字 我试过: $fp = @fsockopen($ip,$port,$errno,$err
$fp = @fsockopen($ip,$port,$errno,$errstr,2);
socket_set_nonblock($fp);
但这不起作用,因为我在套接字打开并等待响应后设置非阻塞。我试图在PHP中实现的功能是否可行?使用不同的函数:和而不是fsockopen()
。这项工作:
$socks = array();
for ($port = 21; $port <= 25; $port++) {
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_nonblock($sock);
@socket_connect($sock, 'localhost', $port);
$socks[$port] = $sock;
}
$startTime = microtime(true);
while ($socks && microtime(true) - $startTime < 3) {
$null = null;
$write = $socks;
socket_select($null, $write, $null, 1);
foreach ($write as $port => $sock) {
$desc = "$port/tcp";
$errno = socket_get_option($sock, SOL_SOCKET, SO_ERROR);
if ($errno == 0) {
echo "$desc open\n";
} elseif ($errno == SOCKET_ECONNREFUSED) {
echo "$desc closed\n";
} elseif ($errno == SOCKET_ETIMEDOUT) {
echo "$desc filtered\n";
} else {
$errmsg = socket_strerror($errno);
echo "$desc error $errmsg\n";
}
unset($socks[$port]);
socket_close($sock);
}
}
foreach ($socks as $port => $sock) {
$desc = "$port/tcp";
echo "$desc filtered\n";
socket_close($sock);
}
$socks=array();
对于($port=21;$port$sock){
$desc=“$port/tcp”;
$errno=socket\u get\u选项($sock,SOL\u socket,SO\u ERROR);
如果($errno==0){
回显“$desc open\n”;
}elseif($errno==SOCKET\u econrefused){
回显“$desc closed\n”;
}elseif($errno==SOCKET\u ETIMEDOUT){
回显“$desc已过滤\n”;
}否则{
$errmsg=socket\u strerror($errno);
回显“$desc error$errmsg\n”;
}
未设置($socks[$port]);
插座关闭($sock);
}
}
foreach($socks as$port=>$sock){
$desc=“$port/tcp”;
回显“$desc已过滤\n”;
插座关闭($sock);
}
请告诉我们您看到的行为。你怎么知道它不起作用了?请提供创建套接字后正在运行的代码。您提供的内容是正确的,因此如果出现问题,可能是在以后的代码中。您提供的代码没有显示任何“正在等待响应”的内容。另外,在创建后设置非阻塞(或将其设置回阻塞)也可以——非常确定没有其他方法。@xaxxon这对打算保持打开状态的套接字很有效,但我只是编写一个端口扫描程序,因此它打开一个套接字,然后在建立连接后立即关闭它。我只是在验证使用该IP和端口创建套接字的可行性。问题是socket\u set\u nonblock()在2秒超时窗口期间不生效,因此如果目标上的端口未打开,它将在尝试下一个socket之前等待整整两秒钟。换句话说,超时窗口阻止了其他套接字的生成。我明白了。由于fsockopen在套接字成功连接之前不会返回,因此在连接完成或失败之后才会调用使其非阻塞的调用@pleasestand的答案看起来不错