Php 使用套接字的TCP连接返回错误结果
这是我用来扫描端口是否打开的代码 有人能修一下吗?它似乎不能正常工作,即使端口关闭,代码始终返回“成功连接” 这是我用80端口测试的ip列表Php 使用套接字的TCP连接返回错误结果,php,sockets,tcp,Php,Sockets,Tcp,这是我用来扫描端口是否打开的代码 有人能修一下吗?它似乎不能正常工作,即使端口关闭,代码始终返回“成功连接” 这是我用80端口测试的ip列表 79.142.126.3 //Connection refused 222.165.195.103 //Connection refused 64.75.193.162 //Connection refused 118.97.197.146 //Port is open 222.134.154.103 //Connection timed out 1
79.142.126.3 //Connection refused
222.165.195.103 //Connection refused
64.75.193.162 //Connection refused
118.97.197.146 //Port is open
222.134.154.103 //Connection timed out
173.0.59.170 //Port is open
以下是输出:
5 sockets connected successfully
79.142.126.3 connected successfully
222.165.195.103 connected successfully
64.75.193.162 connected successfully
118.97.197.146 connected successfully
173.0.59.170 connected successfully
代码看起来不错,但我真的找不到问题
有什么帮助吗?不管怎样,这段代码都会打印出“成功”,失败时也是如此
您可以看到echo“$count sockets connected successfully\n”
和echo“$address connected successfully\n”
不取决于任何条件
只有echo“为$address\n创建的套接字”
取决于条件,但端口关闭时也可以创建套接字
我看没什么问题。将打印一般消息“X sockets connected successfully”(X sockets connected successfully)(您可以将其删除…),但不会打印特定消息“XXXXX connected successfully” 您链接的代码是很久以前编写的,当时我对非阻塞I/O的许多方面了解有限 实际上,这需要一个事件循环,其中有许多实现,但对于这个示例,我将使用的是的库,因为它是一个简单的代码,应该很容易理解。您还可以在上进行循环,这是一个更高的级别,提供了更多的功能 请注意,下面的示例需要PHP5.4+
<?php
// Array of addresses to test
$addresses = [
'192.168.5.150',
'192.168.5.152',
'google.com', // Important note: DNS is resolved synchronously here.
'192.168.5.155', // this can seriously slow down the process as it can block
'192.168.5.20', // for a few seconds, async DNS resolution is non-trivial
'192.168.40.40', // though
];
// The TCP port to test
$port = 80;
// The length of time in seconds to allow host to respond
$timeout = 5;
// This will hold the results
$lookups = [];
// Create a reactor
$reactor = (new \Alert\ReactorFactory)->select();
$count = count($addresses);
$completedCount = 0;
$onComplete = function($address, $result)
use(&$lookups, &$completedCount, $count, $reactor) {
// Cancel the watchers for this address
$reactor->cancel($lookups[$address]['failWatcher']);
$reactor->cancel($lookups[$address]['writeWatcher']);
$reactor->cancel($lookups[$address]['readWatcher']);
// Store the result
$lookups[$address] = $result;
// If there's nothing left to do, stop the reactor
if (++$completedCount == $count) {
$reactor->stop();
}
};
foreach ($addresses as $address) {
// Normalise the address to lower-case, as it will be used as an array key
$address = strtolower($address);
if (!isset($lookups[$address])) {
// Create a socket to connect asynchronously
$sockAddr = "tcp://{$address}:{$port}";
$flags = STREAM_CLIENT_ASYNC_CONNECT;
$socket = stream_socket_client($sockAddr, $errNo, $errStr, 0, $flags);
stream_set_blocking($socket, 0);
// Set up a timeout to watch for failed connections
$failWatcher = function() use($address, $onComplete, $timeout) {
echo "{$address} connect failed: Connect timed out\n";
$onComplete($address, false);
};
$failWatcherId = $reactor->once($failWatcher, $timeout);
// Watch for the stream becoming writable (connection success)
$writeWatcher = function() use($address, $onComplete) {
echo "{$address} connected successfully\n";
$onComplete($address, true);
};
$writeWatcherId = $reactor->onWritable($socket, $writeWatcher);
// Watch for the stream becoming readable (success or explicit fail)
$readWatcher = function() use($address, $onComplete, $socket) {
if ('' === $data = fread($socket, 1024)) {
echo "{$address} connect failed: Server refused connection\n";
$onComplete($address, false);
} else if ($data === false) {
echo "{$address} connect failed: Stream read error\n";
$onComplete($address, false);
} else {
echo "{$address} connected successfully\n";
$onComplete($address, true);
}
};
$readWatcherId = $reactor->onReadable($socket, $readWatcher);
// Store the watcher IDs so they can be destroyed later
$lookups[$address] = [
'failWatcher' => $failWatcherId,
'writeWatcher' => $writeWatcherId,
'readWatcher' => $readWatcherId,
];
}
}
// Set everything going
$reactor->run();
// $lookups is now an array of booleans indicating whether the address resulted
// in a successful connection
如果您能够按顺序测试IP(显然,比并行测试慢),那么您可以简化代码,并从socket\u connect函数获得有用的响应:
<?php
// An array of hosts to check
$addresses = array(
'79.142.126.3', //Connection refused
'222.165.195.103', //Connection refused
'64.75.193.162', //Connection refused
'118.97.197.146', //Port is open
'222.134.154.103', //Connection timed out
'173.0.59.170' //Port is open
);
// The TCP port to test
$testport = 80;
// The length of time in seconds to allow host to respond
$timeout = 5;
foreach ($addresses as $address) {
if (!$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) {
echo "Could not create socket for $address\n";
continue;
}
socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $timeout, 'usec' => 0));
socket_set_option($sock, SOL_SOCKET, SO_SNDTIMEO, array('sec' => $timeout, 'usec' => 0));
if (@socket_connect($sock, $address, $testport)) {
echo "$address connected successfully\n";
}
else {
echo "Unable to connect to $address\n";
}
}
出于好奇,您为什么不使用其他答案之一(比如有29票和奖金的答案)?curl很好,但是socket也很好,速度很快,它是我的最佳选择。@user2203703请在您(在$addresses
数组中)只输入一个IP地址时向我显示确切的输出(此IP上的端口80关闭).我按原样复制了代码,输出为2个插座连接成功118.97.197.146连接成功173.0.59.170连接成功
。您确定没有更改php代码吗?
Unable to conenct to 79.142.126.3
Unable to conenct to 222.165.195.103
Unable to conenct to 64.75.193.162
118.97.197.146 connected successfully
Unable to conenct to 222.134.154.103
173.0.59.170 connected successfully