使用套接字进行 TCP 连接返回错误结果

2023-12-13

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

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 的许多方面了解有限。

实际上,这需要一个事件循环,其中有很多实现,但在这个例子中我将使用@rdlowrey's 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用套接字进行 TCP 连接返回错误结果 的相关文章

  • 显示文件夹并建立这些文件夹的链接

    我正在寻找用 PHP 构建一个目录浏览器 我刚刚开始编写代码 但需要有人帮助我完成或修改它 dir dirname FILE path of the directory to read iterator new RecursiveDirec
  • php-curl 不支持 url 中的 utf-8

    我正在尝试将 http 请求从我的服务器发送到 php 中的另一台服务器 例如 我发送请求的 URL 包含一些 utf8 字符http www aparat com etc api videoBySearch text http www a
  • 执行 mysqli->set_charset() 的永久方法?

    将我可以找到的字符集的所有配置文件和运行时选项设置为 utf 8 后 使用 php 建立的新 mysqli 连接的字符集仍然设置为 latin1 这实际上意味着我必须调用 mysqli gt set charset utf8 每次我连接 m
  • 在 php 中检测 iPad?

    如何向 iPad 查看者提供不同的页面 if SERVER HTTP USER AGENT Mozilla 5 0 iPad U CPU iPhone OS 3 2 like Mac OS X en us AppleWebKit 531 2
  • 如何检查 id 是否已存在 - codeigniter

    我正在尝试检查数据库中的 id 是否已存在 如果不存在则仅插入该 id 而不是其他存在的 id 我尝试执行一个 where 语句来检查数据库中是否存在它们的 id 但即使它们是新信息 它也不会将其插入数据库中 我在这里很迷路 任何指导将不胜
  • LDAP 过滤器用于区分名称

    我使用以下代码成功查询 Active Directory 中的用户 filter objectCategory person samaccountname someusername fields array samaccountname m
  • 按带宽限制成员资格

    我刚刚将 Codeigniter 应用程序部署到 Amazon EC2 使用 S3 作为媒体 使用 RDS 作为 MySQL 我需要根据使用的带宽量限制用户帐户访问 帐户将基于带宽 例如基本帐户 x 每月最多 20GB 等 但是我不知道最好
  • 连接以逗号分隔的字符串,但如果字符串为空,则逗号不应出现在开头[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 这个问题是由拼写错误或无法再重现的问题引起的 虽然类似的问题可能是on topic help on topic在这里 这个问题的解决方式不
  • 正则表达式匹配 2 个或更多单词

    我有一个正则表达式尝试匹配 2 个或更多单词 但它没有按预期工作 我究竟做错了什么 string i dont know do you know preg match a z b 2 string match echo pre print
  • str_getcsv 未正确解析数据

    我对 PHP 的 str getcsv 函数有疑问 我有这个代码
  • orm和pdo的区别

    我对 ORM 和 PDO 之间的区别有点困惑 PDO是一种ORM吗 根据我的理解 ORM 基本上是一种数据映射 PDO 还提供了数据库数据的抽象 PDO 和 ORM 是两个完全不同的东西 PDO 是数据库访问抽象层的具体实现 它使您能够使用
  • 通过 wp_handle_upload 删除未放入上传文件夹中的图像

    我正在将图像保存到上传文件夹 但我正在使用文件放置内容 http php net manual en function file put contents php代替wp 句柄 上传 https codex wordpress org Fu
  • 在 PHP 页面中嵌入 svn 修订号的简单方法?

    注意到这个页面的右下角有 SVN 修订 ID 了吗 我假设这是动态的 我很乐意将其添加到我的一些网站中 就像源代码中的注释一样 以确保代码推送顺利进行 注意 您还可以假设相关站点的工作目录是相关存储库的 svn checkout Edit
  • PHP file_get_contents() 和设置请求标头

    使用 PHP 是否可以发送 HTTP 标头file get contents 我知道您可以从您的php ini文件 但是 您是否还可以发送其他信息 例如HTTP ACCEPT HTTP ACCEPT LANGUAGE and HTTP CO
  • 原始 POST 数据是什么?

    我试图理解原始 POST 数据的含义 PHP 手册页 HTTP RAW POST DATA http php net manual en reserved variables httprawpostdata php只是声明这个变量包含Raw
  • PHP:分离业务逻辑和表示逻辑,值得吗? [复制]

    这个问题在这里已经有答案了 可能的重复 为什么要在 PHP 中使用模板系统 https stackoverflow com questions 436014 why should i use templating system in php
  • ajax - 检查用户名是否存在+如果存在则返回消息

    我试图检查用户想要的用户名是否已被使用 而无需发送表单 基本上是用户名字段的模糊 我遇到了一些麻烦 有几个问题 我有我的输入字段加上js
  • PHP cURL 代理带标头?

    我正在制作一个 PHP 图像代理脚本 我需要它不仅能够回显其请求的图像的内容 而且还能够以相同的方式重现图像请求的标头 我见过一个 另一个 但没有同时看到过 这些 cURL 选项让我感到困惑 我该怎么做 抱歉 我不确定你想要什么 这是从图像
  • 将 IP 地址与 IPv6 块进行比较

    我使用 PHP 将用户 IP 地址与 IP 块列表进行比较 其中大多数是 IPv4 但其中一些是 IPv6 我从用户那里获得的 IP 地址始终与 IPv4 兼容 至少我是这么假设的 我将如何比较这个 这就是我现在正在使用的 function
  • 使用 foreach 进行复杂的多维关联数组处理

    我不得不再次问这个问题 抱歉 但我在尝试处理这个数组时遇到了问题 我尝试了几种不同的方法 但没有一个是正确的 这是数组 Array search gt Array response gt Array errors gt number of

随机推荐