TCP连接使用套接字返回false结果

 手机用户2502854107 发布于 2023-02-13 10:03

这是我用来扫描端口的代码,如果它是打开的.

/sf/ask/17360801/

有人可以试着解决它吗?它似乎不能正常工作,即使端口关闭,代码总是返回"成功连接"

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

代码看起来很好,但我真的找不到问题.

有什么帮助吗?

1 个回答
  • 您链接的代码是很久以前编写的,当时我对非阻塞I/O的许多方面的理解有限.

    实际上这需要一个事件循环,其中有许多实现,但是对于这个例子,我将使用@rdlowrey的Alert库,因为它是一个非常容易理解的极简主义代码.您还可以在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
    

    2023-02-13 10:06 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有