Python. Redirect stdout to a socket

There is the makefile function in Python's socket class:

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

Return a file object associated with the socket. The exact returned type depends on the arguments given to makefile(). These arguments are interpreted the same way as by the built-in open() function.

Closing the file object won’t close the socket unless there are no remaining references to the socket. The socket must be in blocking mode; it can have a timeout, but the file object’s internal buffer may end up in a inconsistent state if a timeout occurs.

You can read how to use it in Mark Lutz's book (chapter 12, "Making Sockets Look Like Files and Streams").

An example from the book (the idea is simple: make a file object from a socket with socket.makefile and link sys.stdout with it):

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

Server side:

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

This assumes Python3.

If no one else have a better way of just redirecting output to a socket from a process, this is a solution you could work with.