pythonpython-2.7shellconnectiontwisted

Simple Administrative Application in Python based on Twisted hangs and does not send data


I am trying to write a simple Administrative App which gives me access to computers shell through telnet (this is only test for Py0thon programming practice). When I connect to my server then I have only black screen in terminal (Windows telnet client) but in log of my program there is the output from the subprocess and it does not get sent to the client.

I have searched on Google for many solutions but none of them worked with Twisted lib properly and result was the same

my server code:

# -*- coding: utf-8 -*-

from subprocess import Popen, PIPE
from threading import Thread
from Queue import Queue # Python 2

from twisted.internet import reactor
from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver
import sys

log = 'log.tmp'

def reader(pipe, queue):
    try:
        with pipe:
            for line in iter(pipe.readline, b''):
                queue.put((pipe, line))
    finally:
        queue.put(None)

class Server(LineReceiver):
    
    def connectionMade(self):
        self.sendLine("Creating shell...")
        self.shell = Popen("cmd.exe", stdout=PIPE, stderr=PIPE, bufsize=1, shell=True)
        q = Queue()
        Thread(target=reader, args=[self.shell.stdout, q]).start()
        Thread(target=reader, args=[self.shell.stderr, q]).start()
        for _ in xrange(2):
            for pipe, line in iter(q.get, b''):
                if pipe == self.shell.stdout:
                    sys.stdout.write(line)
                else:
                    sys.stderr.write(line)
        self.sendLine("Shell created!")
            
    def lineReceived(self, line):
        print line
        #stdout_data = self.shell.communicate(line)[0]
        self.sendLine(line)
    

if __name__ == "__main__":      
    ServerFactory = Factory.forProtocol(Server)
    
    reactor.listenTCP(8123, ServerFactory) #@UndefinedVariable
    reactor.run() #@UndefinedVariable

Solution

  • You mixed a blocking program with a non-blocking program. The non-blocking parts don't get to run because the blocking parts are blocking. The blocking parts don't work because they rely on the non-blocking parts running.

    Get rid of the Popen and Queue and Thread and use reactor.spawnProcess instead. Or get rid of the Twisted and use more threads for the networking.