Doge log

Abby CTO 雑賀 力王のオフィシャルサイトです

ディスクリプタパッシング自分用メモ

python2.6
親はメインのacceptに専念。
子プロセス側でecho処理。

from multiprocessing import _multiprocessing
import os
import socket
import time

class FDDispatchServer(object):

    def __init__(self):
        self.is_child = None

    def fork(self):
        pid = os.fork()

        if pid > 0:
            self.is_child = 0
        else:
            self.is_child = 1

    def ready(self):
        if self.is_child:
            self._child_ready()
        else:
            self._parent_ready()

    def _parent_ready(self):
        time.sleep(1)
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.bind(('localhost' , 6000))
        sock.listen(10)

        send_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        send_sock.connect('test.sock')
        while True:
            con, addr = sock.accept()
            fd = con.fileno()
            _multiprocessing.sendfd(send_sock.fileno(), con.fileno())
            con.close()

    def _child_ready(self):
        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        sock.bind('test.sock')
        sock.listen(10)
        conn, addr = sock.accept()
        while True:
            fd = _multiprocessing.recvfd(conn.fileno())
            client = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
            data = client.recv(8192)
            #print(data)
            client.send(data)
            client.close()
            os.close(fd)


server = FDDispatchServer()
server.fork()
server.ready()

recvmsg(2)はブロックするのでそこを起点に回す。
os.closeじゃないとうまく閉じられなかった。
盲点だったな。