在 PHP 中进行 TELNET 的正确且快速的方法。套接字或 cURL

Posted

技术标签:

【中文标题】在 PHP 中进行 TELNET 的正确且快速的方法。套接字或 cURL【英文标题】:Proper and fast way to TELNET in PHP. Sockets or cURL 【发布时间】:2012-01-14 17:17:16 【问题描述】:

几乎所有 php 中的 TELNET 实现示例都使用套接字 (fsockopen)。这对我不起作用,因为它需要不可接受的时间(约 60 秒)。

我尝试过 fsockopen 用于其他目的,发现它与 cURL 相比速度较慢。

问题 #1: 为什么套接字这么慢?

更新:我发现我们需要设置stream_set_timeout函数,我们可以控制socket执行时间。我很好奇如何设置正确的超时时间或如何在收到响应后使其“停止等待”。


我无法使用 cURL 实现相同的功能。我应该把需要发送到 telnet 的命令放在哪里? CURLOPT_CUSTOMREQUEST 是正确的选择吗?我正在做这样的事情:

class TELNETcURL

    public $errno;
    public $errstr;
    private $curl_handle;
    private $curl_options = array(
        CURLOPT_URL => "telnet://XXX.XXX.XXX.XXX:<port>",
        CURLOPT_TIMEOUT => 40,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_HEADER => FALSE,
        CURLOPT_PROTOCOLS => CURLPROTO_TELNET
    );

    function __construct()
        $this->curl_handle = curl_init();
        curl_setopt_array($this->curl_handle, $this->curl_options);
    

    public function exec_cmd($query) 
        curl_setopt($this->curl_handle, CURLOPT_CUSTOMREQUEST, $query."\r\n");
        $output = curl_exec($this->curl_handle);
        return $output;
    

    function __destruct()
        curl_close($this->curl_handle);
    


然后类似这样:

$telnet = new TELNETcURL();
print_r($telnet->exec_cmd("<TELNET commands go here>"));    

我在 curl_exec 命令上收到“最大执行时间超过 30 秒”。

问题 #2: cURL 实现有什么问题?

【问题讨论】:

【参考方案1】:

套接字并不慢。套接字是通信的基础。 Curl 使用套接字打开到远程服务器的连接。一切都适用于套接字(我认为)。 我认为您不能使用 curl 来使用 telnet 服务,嗯,这并不完全正确,我想您可以连接并发送单个命令。 Curl 在设计时考虑了 http 协议,它是无状态的(您打开连接、发送请求、等待回复并关闭连接)。 套接字是唯一的选择。

我在 curl_exec 命令上收到“最大执行时间超过 30 秒”。

我的猜测是远程服务器是罪魁祸首。检查它是否可以使用常规终端客户端,或者增加 php ini 中的 max_execution_time。

更新

似乎可以使用 curl 进行远程登录,请检查: http://www.cs.sunysb.edu/documentation/curl/

但我仍然认为你最好使用套接字。

【讨论】:

套接字...我注意到套接字仅在达到超时后才关闭连接。意思是,如果我设置 1 秒超时,套接字将执行 1 秒(不少于)。我需要在操作完成后立即使用它,因为我在实时应用程序中使用它。如果我设置小超时,操作可能无法完成(如果操作时间很长),那么我什么都不会收到。使用 cURL,它会立即完成。所以我不知道如何用套接字来做到这一点。请指教。 是的,cURL支持TELNET,但是我不知道如何在PHP中实现。我没有在网上找到工作示例。【参考方案2】:

您需要做的是使用非阻塞 IO,然后轮询响应。你现在正在做的是等待/挂起一个永远不会出现的响应——因此超时。

就我个人而言,我用 php 编写了很多套接字应用程序,它们工作得很好——我讨厌 cURL 有错误、笨重和高度不安全……只要阅读他们的错误列表,你就会感到震惊。

阅读优秀的 PHP 手册,其中包含许多有关如何进行轮询 IO 的示例,他们甚至为您提供了一个示例 telnet 服务器和客户端。

【讨论】:

还要确保您没有被防火墙阻止【参考方案3】:

使用 pfsockopen 而不是 fopensock ..它更快并且一直保持连接状态

【讨论】:

以上是关于在 PHP 中进行 TELNET 的正确且快速的方法。套接字或 cURL的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 PHP shell_exec() 执行 telnet 命令

使用 PHP 上传脚本搜索免费且快速的 Jquery

HTTP系列二: 使用telnet模拟http请求

PHP 快速排序

SMTP Telnet 和 PHP 没有从 HELO 得到任何响应

在 PHP 中使用 Telnet 发送退格或删除