views:

488

answers:

1

Hello,

I have a Python Server finally working and responding to multiple command's with the output's, however I'm now having problem's with PHP receiving the full output. I have tried commands such as fgets, fread, the only command that seems to work is "fgets".

However this only recieve's on line of data, I then created a while statement shown bellow:

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

However it seems the Python server is not sending a Feof at the end of the output so the php page times out and does not display anything. Like I said above, just running echo fgets($handle), work's fine, and output's one line, running the command again under neither will display the next line e.t.c

I have attached the important part of my Python Script bellow:

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()

I have also attached the full PHP script:

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

Thanks, Ashley

+1  A: 

Hi, I believe you need to fix your server code a bit. I have removed the inner while loop. The problem with your code was that the server never closed the connection, so feof never returned true.

I also removed the + " &" bit. To get the output, you need to wait until the process ends anyway. And I am not sure how the shell would handle the & in this case.

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()

BTW, you need to use the while-loop in your php script. fgets returns until a single line only.

codeape
Work's perfectly thanks, one last thing, currently when I Cntrl+C out of the program to close it, it does not cleanly close the section. I looked at running a while statement for cntr+something that would then close the socket. But I didn't know if I could do that while still running the while statement of the software.
AshleyUK
I assume you mean the server program, not the PHP client? In that case, I believe that the s.close() within the last finally clause should close the socket when Ctrl-C is used as well. When you exit the server with Ctrl-C, you should see "closing socket" printed to the console. Do you not see that?
codeape
When I use Cntrl+C i get : Traceback (most recent call last): File "vzctl.py", line 15, in <module> con, addr = s.accept() File "/usr/local/lib/python2.5/socket.py", line 167, in accept sock, addr = self._sock.accept()KeyboardInterruptIt does free up the socket now, I hadn't properly tested it since your code change, however I'm not sure if the error's that are shown after closing socket are ok?
AshleyUK
In a Python program, pressing Ctrl-C raises a KeyboardInterrupt. I've added an except clause to the server code that will handle this exception (by doing nothing).
codeape
Work's perfect now. Thanks Codeape
AshleyUK