Питон. Перенаправить stdout в сокет
Я запускаю свой скрипт на компьютере "A", затем подключаюсь к компьютеру" A "с компьютера" B " через мой скрипт. Я отправляю свое сообщение на компьютер "A", и мой скрипт запускает его с инструкцией " exec ()".
Я хочу видеть результат выполнения моего сообщения на компьютере "A", через сокет на компьютере" B".
Я пытаюсь изменить sys.stdout = socket_response
но есть ошибка: "объект сокета не имеет атрибута write ()"
Итак, как я могу перенаправить стандартный вывод (для печати или 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
я подключился к скрипту с помощью шпатлевки и отправил "print ' abc'", а затем получил ответ 'abc'
2 ответов
здесь makefile
функция в классе сокетов python:
гнездо.make-файл(mode= 'r', buffering=None,*, encoding=None, ошибки=нет, новая строка=нет)
возвратить связанный с сокетом. Точное вернулся тип зависит от аргументов, заданных для makefile(). Эти аргументы интерпретируется так же, как и встроенной функцией open ().
закрыть файл объект не закроет сокет, если нет оставшиеся ссылки на сокет. Сокет должен быть заблокирован режим; он может иметь тайм-аут, но внутренний буфер файлового объекта может в конечном итоге в несогласованном состоянии, если тайм-аут происходит.
как его использовать вы можете прочитать в книге Марка Лутца (глава делает сокеты похожими на файлы и потоки)
пример из книги (идея проста: сделать объект файла из сокета с 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
сервер:
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.
Если ни у кого нет лучшего способа просто перенаправить вывод в сокет из процесса, это решение, с которым вы можете работать.