在PHP 5.x中使用fsockopen循环Fget

3 投票
1 回答
1921 浏览
提问于 2025-04-15 12:24

我终于让我的Python服务器正常工作了,它可以响应多个命令并返回结果。不过,现在我遇到了一个问题,就是PHP无法接收到完整的输出。我尝试了像fgets和fread这样的命令,结果发现只有“fgets”这个命令好像有效。

不过,这个命令只能接收到一行数据。于是我创建了一个下面的while循环:

 while (!feof($handle)) {
    $buffer = fgets($handle, 4096);
    echo $buffer;
}

但是看起来Python服务器没有在输出结束时发送Feof信号,所以PHP页面超时了,什么都不显示。就像我之前说的,单独运行echo fgets($handle)是没问题的,它能输出一行,但如果再运行一次,就无法显示下一行等等。

我在下面附上了我的Python脚本的重要部分:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", port))
s.listen(5)
print "OK."
print "  Listening on port:", port
import subprocess
while 1:
    con, addr = s.accept()
    while True:
        datagram = con.recv(1024)
        if not datagram:
            break
        print "Rx Cmd:", datagram
        print "Launch:", datagram
        process = subprocess.Popen(datagram+" &", shell=True, stdout=subprocess.PIPE)
        stdout, stderr = process.communicate()
        con.send(stdout)
    con.close()
s.close()

我也附上了完整的PHP脚本:

<?php
$handle = fsockopen("tcp://xxx.xxx.xxx.xxx",12345);
fwrite($handle,"ls");
echo fgets($handle);
fclose($handle);
?>

谢谢,
Ashley

1 个回答

1

我觉得你需要稍微修正一下你的服务器代码。我把里面的那个 while 循环去掉了。你代码的问题在于服务器从来没有关闭连接,所以 feof 这个函数永远不会返回真。

我还去掉了 + " &" 这一部分。要得到输出,你反正得等到进程结束。而且我不太确定在这种情况下,shell 会怎么处理 &

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", port))
s.listen(5)
print "OK."
print "  Listening on port:", port
import subprocess
try:
    while 1:
        con, addr = s.accept()
        try:
            datagram = con.recv(1024)
            if not datagram:
                continue
            print "Rx Cmd:", datagram
            print "Launch:", datagram
            process = subprocess.Popen(datagram, shell=True, stdout=subprocess.PIPE)
            stdout, stderr = process.communicate()
            con.send(stdout)
        finally:
            print "closing connection"
            con.close()
except KeyboardInterrupt:
    pass
finally:
    print "closing socket"
    s.close()

顺便说一下,你在 php 脚本中需要使用 while 循环。因为 fgets 只会返回一行内容。

撰写回答