【问题标题】:PHP - fsockopen() times out instead of returning false?PHP - fsockopen() 超时而不是返回 false?
【发布时间】:2012-08-12 11:38:42
【问题描述】:

我正在尝试使用 fsockopen() 检查 Selenium 服务器是否正在运行。当服务器运行时,应该设置常量。当它不是常量时,不设置。这是使用以下代码完成的:

if(!defined('TEST_SELENIUM')){
    $fp = @fsockopen('localhost', 4444);
    if ($fp !== false) {
        define('TEST_SELENIUM', true);
        fclose($fp);
    }
}

当服务器未运行时(在 Windows 7 上)出现问题。 fsockopen() 不是从找到关闭的端口返回 false,而是在尝试与端口通信时停止。当服务器运行时,它会使用 netstat 快速显示。当服务器关闭时,netstat 不会从端口 4444 返回任何内容。根据我对 fsockopen() 的理解,这应该立即返回 false。但同样,它只是在尝试与端口通信时停滞不前。我不想在这里添加超时,因为这不是应用程序中应该有任何类型的停顿的点。另外,我应该注意到这似乎在 Linux 上以我期望的方式工作。但是,它在 Windows 7 上失败了。谁能告诉我我做错了什么?非常感谢!

【问题讨论】:

    标签: php sockets selenium port


    【解决方案1】:

    如果不添加超时,您将无法执行此操作。这与 PHP 的实现无关——这正是 TCP 套接字连接应该如何工作的。

    因为 TCP 使用确认 (ACK) 来保证数据包的传递和排序,所以当您启动 TCP 连接时,客户端会发送一个 SYN 数据包,并等待返回的 SYN/ACK 数据包。客户端将继续等待这个返回的数据包,直到它被接收到,或者客户端决定它等待的时间足够长并放弃 - 这是fsockopen() 接受的超时参数。

    当您运行 netstat 时,它会查看绑定到 本地计算机上的 TCP 堆栈的应用程序 - 这意味着它能够确定端口是否在使用中而无需尝试连接到它。因此,它能够立即报告套接字是否在使用中。

    实际上你有两个选择。

    • 提供超时。请记住,超时参数可以是浮点数(因此可以小于 1 秒),因此如果您正在检查本地计算机,则可以将其设置得非常低。只是在我的 Windows XP 机器上测试它,我发现我可以将它设置为 0.001 (1ms) 并且它成功连接到正在运行的服务,并为未绑定的端口返回 FALSE。这 1 毫秒的超时也适用于我(诚然相对安静且完全千兆)LAN 上的其他机器。 YMMV,但 5 毫秒 (0.005) 在高速网络中应该绰绰有余。
      例如,这行代码对我来说效果很好,会导致脚本等待 最大 1ms:
    define('TEST_SELENIUM', (bool) @fsockopen('localhost', 4444, $en, $es, 0.001));
    
    • shell_exec('netstat'); 并解析输出。这肯定只有在您检查本地机器时才有效,并且可能不会比 1ms 超时方法快。它也不是很便携,因为各种操作系统上的 netstat 实用程序可能会产生非常细微的不同输出 - 不同的列顺序、不同的分隔符等。

    另外值得注意的是,如果 TCP 堆栈被配置为主动拒绝发送到未绑定端口的数据包(通过返回 RST 数据包),那么fsockopen() 将立即失败。这可能就是您说this appears to work the way I would expect it should on Linux 的原因——您测试它的Linux 实例就是以这种方式配置的。可能有一些注册表设置允许您将 Windows 配置为以这种方式运行,尽管我不知道它是什么 - SuperUser 的人可以帮助您。

    【讨论】:

    • 感谢您非常详细的回答。该程序将主要在 Linux 上运行,因此我可能会尝试您提到的注册表设置更改可能可用。这确实是我正在寻找的解决方案。但如果需要,我会确保使用适当的超时时间。
    猜你喜欢
    • 2015-05-11
    • 1970-01-01
    • 2021-06-04
    • 2023-03-20
    • 2014-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多