import socket
import struct
import json
import os

RPC_VERSION = 1

def msg_send(sock, msg):
    j = json.dumps(msg)
    header = struct.pack('!LL', RPC_VERSION, len(j))
    sock.sendall(b'%b%b' % (header, j.encode('utf-8')))

def msg_recv(sock):
    buff = b''
    while len(buff) < 8:
        buff += sock.recv(1024)

    (version, length) = struct.unpack('!LL', buff[0:8])
    assert RPC_VERSION == version

    buff = buff[8:]

    while len(buff) < length:
        buff += sock.recv(1024)

    assert len(buff) == length

    return json.loads(buff.decode('utf-8'))

class UnknownRPCError(Exception):
    pass

class RPCError(Exception):
    pass

class RPC(object):
    def __init__(self, sock, method):
        self.sock = sock
        self.method = method

    def __call__(self, *args, **kwargs):
        msg_send(self.sock, ['rpc', self.method, args, kwargs])
        [msg_type, msg] = msg_recv(self.sock)
        assert msg_type in ['return', 'error']
        if msg_type == 'error':
            if msg == 'UnknownRPCError':
                raise UnknownRPCError
            raise RPCError(msg)

        return msg


class Server(object):
    def __init__(self, path):
        self.path = path
        self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self.socket.bind(self.path)
        self.socket.listen(1)
        self.funs = {}

    def register(self, name, function):
        self.funs[name] = function

    def start(self):
        try:
            while True:
                conn, _ = self.socket.accept()
                [msg_type, method, args, kwargs] = msg_recv(conn)
                assert msg_type == 'rpc'
                if method not in self.funs:
                    msg_send(conn, ['error', 'UnknownRPCError'])
                else:
                    try:
                        ret = self.funs[method](*args, **kwargs)
                        msg_send(conn, ['return', ret])
                    except Exception as e:
                        try:
                            msg_send(conn, ['error', str(e)])
                        except:
                            pass
        finally:
            try:
                if os.path.exists(self.path):
                    os.remove(self.path)
            except: # pylint: disable=bare-except
                pass

class Client(object):
    def __init__(self, path):
        self.__path = path
        self.__socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self.__socket.connect(self.__path)

    def __getattr__(self, method):
        return RPC(self.__socket, method)

    def fileno(self):
        return self.__socket.fileno()

    def read(self):
        return self.__socket.recv(1024)

    def close(self):
        self.__socket.close()

@@ -7,16 +7,30 @@
  socket%0A
+import select%0A
 import s
@@ -269,11 +269,64 @@
 f = 
-b''
+sock.recv(1024)%0A    if buff == b'':%0A        return None%0A
 %0A   
@@ -1553,67 +1553,561 @@
     
-while True:%0A                conn, _ = self.socket.accept()%0A
+conns = %5Bself.socket%5D%0A            while True:%0A                readable, _, _ = select.select(conns, %5B%5D, %5B%5D)%0A                if self.socket in readable:%0A                    conn, _ = self.socket.accept()%0A                    conns.append(conn)%0A                    readable.remove(self.socket)%0A                for conn in readable:%0A                    msg = msg_recv(conn)%0A                    if msg is None:%0A                        conn.close()%0A                        conns.remove(conn)%0A                        continue%0A                    else:%0A        
     
@@ -2152,36 +2152,29 @@
 wargs%5D = msg
-_recv(conn)%0A
+%0A    
             
@@ -2214,24 +2214,28 @@
             
+  
+  
 if method no
@@ -2250,16 +2250,20 @@
 f.funs:%0A
+    
         
@@ -2327,32 +2327,36 @@
                 
+  
+  
 else:%0A          
@@ -2357,37 +2357,45 @@
                 
+    
 try:%0A
+    
                 
@@ -2459,32 +2459,36 @@
                 
+    
 msg_send(conn, %5B
@@ -2519,24 +2519,28 @@
             
+   
+ 
 except Excep
@@ -2566,37 +2566,45 @@
                 
+    
 try:%0A
+    
                 
@@ -2677,16 +2677,20 @@
     
+    
 except:%0A
     
@@ -2685,16 +2685,20 @@
 except:%0A
+    
         

Make unix_rpc.Server properly handle multiple connections