在PHP中打开异步套接字 [英] Open asynchronous sockets in PHP
问题描述
我正在用PHP编写支持较小范围(例如端口21-25)的端口扫描程序.通过AJAX将要扫描的端口和IP发送到服务器,然后PHP尝试在每个端口上打开一个套接字.如果成功,则打开端口;如果超时,则关闭端口.
I am writing a port scanner in PHP that supports small ranges (e.g., ports 21-25). The ports and IP to be scanned are sent to the server via AJAX, and then PHP attempts to open a socket on each of the ports. If it succeeds, the port is open, if it times out, the port is closed.
当前,尽管同时为端口21-25发送了所有AJAX请求,但是每个套接字仅在最后一个套接字关闭后才打开.因此,检查端口21,关闭插座,然后检查端口22,依此类推.我想要的是同时检查所有端口,所以我要一次打开多个套接字.
Currently, despite sending all of the AJAX requests at the same time for ports 21-25, each socket is only opened after the last one closes. So, port 21 is checked, the socket is closed, and then port 22 is checked, and so on. What I want is for all ports to be checked concurrently, so I'd be opening several sockets at once.
我尝试过:
$fp = @fsockopen($ip,$port,$errno,$errstr,2);
socket_set_nonblock($fp);
但是这不起作用,因为在套接字已经打开并等待响应之后,我将设置为非阻塞状态.我想在PHP中做些什么吗?
But this doesn't work, as I'm setting non-block AFTER the socket has already been opened and is waiting for a response. Is what I'm trying to do possible in PHP?
推荐答案
使用不同的功能: socket_create()
和 socket_connect()
而不是fsockopen()
.这有效:
Use different functions: socket_create()
and socket_connect()
instead of fsockopen()
. This works:
$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);
}
这篇关于在PHP中打开异步套接字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!