蟒蛇。将stdout重定向到套接字

时间:2014-01-29 11:48:06

标签: python sockets redirect stdout

我在“A”计算机上运行我的脚本,然后通过我的脚本从“B”计算机连接到“A”计算机。我将消息发送到计算机“A”,我的脚本使用'exec()'指令运行它。

我希望通过“B”计算机上的套接字在“A”计算机上看到执行结果我的消息。 我尝试更改sys.stdout = socket_response,但有一个错误:“Socket对象没有属性write()”

那么,如何通过套接字连接将标准输出(对于print或exec())从“A”计算机重定向到“B”计算机。“

在我的剧本中会有某种“python解释器”。

抱歉,我无法回答我自己的问题

感谢所有人!

我用简单的方式,这给了我@Torxed。这里是我的猴子代码(这只是一个例子,不是我的真实剧本)

    #-*-coding:utf-8-*-
import socket
import sys

class stdout_():

    def __init__(self, sock_resp):
        self.sock_resp = sock_resp

    def write(self, mes):
        self.sock_resp.send(mes)


MY_IP = 'localhost'
MY_PORT = 31337

srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Start server")
old_out = sys.stdout


srv.bind((MY_IP, MY_PORT))
srv.listen(0)
sock_resp, addr_resp = srv.accept()
new_out = stdout_(sock_resp)
sys.stdout = new_out
#sys.stdout = sock_resp ### sock_object has no attribute 'write'
while 1:
    try:
        a = sock_resp.recv(1024)
        exec(a)
    except socket.timeout:
        #print('server timeout!!' + '\n')
        continue

我用Putty连接脚本并发送“print'abc'”然后我收到回答'abc'

2 个答案:

答案 0 :(得分:4)

python套接字类中有makefile函数:

  

socket。 makefile (mode ='r',buffering = None,*,encoding = None,   errors = None,newline = None)

     

返回与套接字关联的文件对象。确切的返回   type取决于给makefile()的参数。这些论点是   解释方式与内置的open()函数相同。

     

关闭文件对象不会关闭套接字,除非没有   对套接字的剩余引用。套接字必须处于阻塞状态   模式;它可以有超时,但文件对象的内部缓冲区可能   如果发生超时,则以不一致状态结束。

如何使用它,您可以阅读Mark Lutz书(chapter Making Sockets Look Like Files and Streams

本书中的示例(想法很简单:使用socket.makefile从套接字创建文件对象并使用链接sys.stdout):

def redirectOut(port=port, host=host):
    """
    connect caller's standard output stream to a socket for GUI to listen
    start caller after listener started, else connect fails before accept
    """
    sock = socket(AF_INET, SOCK_STREAM)
    sock.connect((host, port))                # caller operates in client mode
    file = sock.makefile('w')                 # file interface: text, buffered
    sys.stdout = file                         # make prints go to sock.send
    return sock                               # if caller needs to access it raw

答案 1 :(得分:1)

服务器端:

from subprocess import Popen, STDOUT, PIPE
from socket import socket
from time import sleep

server_sock = socket()
server_sock.bind(('', 8000))
server_sock.listen(4)

def close_process(p):
    p.stdin.close()
    p.stdout.close()

while 1:
    try:
        client, client_address = server_sock.accept()
        data = client.recv(8192)
    except:
        break
    # First, we open a handle to the external command to be run.
    process = Popen(data.decode('utf-8'), shell=True, stdout=PIPE, stdin=PIPE, stderr=STDOUT)
    # Wait for the command to finish
    # (.poll() will return the exit code, None if it's still running)
    while process.poll() == None:
        sleep(0.025)
    # Then we send whatever output the command gave us back via the socket
    # Python3: sockets never convert data from byte objects to strings,
    # so we'll have to do this "manually" in case you're confused from Py2.X
    try:
        client.send(bytes(process.stdout.read(), 'UTF-8'))
    except:
        pass

    # And finally, close the stdout/stdin of the process,
    # otherwise you'll end up with "to many filehandles openened" in your OS.
    close_process(process)
    client.close()

server_sock.close()

这假设是Python3。

如果没有其他人可以更好地将输出重定向到流程中的套接字,那么这是一个可以使用的解决方案。