php - 从 PHP 向 TCP/IP 控制台执行命令的最佳方式

标签 php console tcp fsockopen

在我开始之前,请原谅我的英语,我来自荷兰:)

我有一个关于使用 PHP 的 fsockopen 的问题.

我的先决条件

基本上,我有一个在后台运行的 Windows 程序,它有一个通过 TCP/IP 的远程控制台,我需要连接到它以便执行一些命令。我可以使用 KiTTY 连接到该控制台,并毫无问题地执行我的命令。

我的解决方案

所以我现在遇到的问题是,我需要能够从浏览器执行这些命令。我在网上搜索了执行此操作的最佳方法,我发现是使用 PHP 的 fsockopen。连接到我的控制台。我试过的代码如下:

$SOCKET = fsockopen("127.0.0.1", 12101, $errno, $errstr);

if($SOCKET){
 echo "Connected!";
}

$firstRead = fread($SOCKET, 8000);

echo($firstRead);

并使用 fputs发送命令:

fputs($SOCKET, "HELP \r\n");

然后,读出我的回应:

$response = fread($SOCKET, 8000);
echo $response;

问题

但是我在测试这个的时候遇到了一些奇怪的问题。 一旦我执行了像“HELP”这样的命令,我就可以从我的 KiTTY session 中看到该命令已被执行并且我得到了响应,但是当我用“fread”读出响应时我什么也得不到。但是当我使用循环像这样读出它时,它几乎每次都会在第二次尝试时从控制台读取一些东西:

do {
    $response = fread($SOCKET, 8000);
    $i++;
} while (strlen($response) < 5 || $i < 5);

(有时,它会在第一次尝试时从控制台读取一些内容,但大多数情况下它只会在第二次尝试时读取一些内容)。

问题

现在我的问题是(是),为什么它的行为如此奇怪?是因为我做错了什么吗?这真的是最好的方法吗?

旁注

当它工作时,我需要能够用一堆 AJAX requests 调用这些 PHP 函数(或类似的东西)并获得在浏览器中显示的响应。这是绝对必须的,因此在编写可能的答案时请牢记这一点:)

谢谢大家!

最佳答案

当您在 PHP 中使用 fsockopen 创建套接字时,您可能还想指定它是阻塞的还是非阻塞的,如果是非阻塞套接字,函数 socket_read 将在错误或连接关闭时返回 false,或者在接收到一些数据之前返回空字符串,如果是阻塞套接字,而不是当你读取它时,它将阻塞直到有一些要读取的数据(如果超时则为空字符串)。 您描述的行为似乎是非阻塞的。

要更改阻塞类型,有:socket_set_blocksocket_set_nonblock

当您的套接字代码正常工作时,AJAX 请求不会有任何问题,但请记住在 PHP 套接字中设置超时,否则如果服务器关闭或太慢,请求将失败并显示错误 (如果超过 set_time_limit,则 php 超时,这是 fatal error ,或者是具有浏览器超时常量的 JavaScript。

这里是 socket_read 手册的链接和 socket_write ,我认为它更适合 freadfputs

关于php - 从 PHP 向 TCP/IP 控制台执行命令的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49361651/

相关文章:

php - 如何使用 getQuery()->getOneOrNullresult() 返回

javascript - session 过期时如何处理 laravel TokenMismatchException

php - Firestore REST API : Query parameters type of object

console - Vagrant 向上 "error while executing VBoxManage"

android - 当 InetAddress 改变时 ServerSocket 会发生什么?

tcp - 从 * char eth/ip/tcp 打包程序表示中获取 TCP 选项(超出 tcphdr->doff)

php - 正则表达式匹配段落标签之间的文本

控制台中的 AngularJs 范围变量

command-line - 在Dart中使用子命令实现控制台应用程序的最简单方法是什么?

networking - NAT 实现