Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中打开异步套接字_Php_Sockets_Asynchronous - Fatal编程技术网

在PHP中打开异步套接字

在PHP中打开异步套接字,php,sockets,asynchronous,Php,Sockets,Asynchronous,我正在用PHP编写一个支持小范围(例如端口21-25)的端口扫描程序。要扫描的端口和IP通过AJAX发送到服务器,然后PHP尝试在每个端口上打开一个套接字。如果成功,则端口打开;如果超时,则端口关闭 目前,尽管为端口21-25同时发送所有AJAX请求,但每个套接字只有在最后一个套接字关闭后才会打开。因此,检查端口21,关闭插座,然后检查端口22,依此类推。我想要的是同时检查所有端口,因此我将同时打开几个套接字 我试过: $fp = @fsockopen($ip,$port,$errno,$err

我正在用PHP编写一个支持小范围(例如端口21-25)的端口扫描程序。要扫描的端口和IP通过AJAX发送到服务器,然后PHP尝试在每个端口上打开一个套接字。如果成功,则端口打开;如果超时,则端口关闭

目前,尽管为端口21-25同时发送所有AJAX请求,但每个套接字只有在最后一个套接字关闭后才会打开。因此,检查端口21,关闭插座,然后检查端口22,依此类推。我想要的是同时检查所有端口,因此我将同时打开几个套接字

我试过:

$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的答案看起来不错