gpt4 book ai didi

php - TCP 连接使用套接字返回错误结果

转载 作者:可可西里 更新时间:2023-11-01 02:31:58 27 4
gpt4 key购买 nike

这是我用来扫描端口是否打开的代码。

https://stackoverflow.com/a/8957053/2203703

有人可以尝试修复它吗?它似乎无法正常工作,即使端口关闭,代码总是返回“成功连接”

这是我用 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
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

代码看起来不错,但我真的找不到问题。

有什么帮助吗?

最佳答案

您链接的代码是很久以前写的,当时我对非阻塞 I/O 的许多方面的了解有限。

这确实需要一个事件循环,它有很多实现,但对于这个例子,我将使用 @rdlowreyAlert库,因为它是一个应该相当容易理解的极简代码。您也可以在 React 循环,这是更高级别并提供更多功能。

请注意,下面的示例需要 PHP 5.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

关于php - TCP 连接使用套接字返回错误结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20360167/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com