【python-網(wǎng)絡(luò)通信】這是一個(gè)用socket實(shí)現(xiàn)的簡(jiǎn)單的python RPC服務(wù)器/客戶(hù)端。* 通過(guò)客戶(hù)端/服務(wù)器共用的密碼認(rèn)證客戶(hù)端* 使用JSON序列化函數(shù)調(diào)用有效負(fù)載

"""
This is a RPC server/client implementation using socket
* It authenticate the client with a secret shared by client/server
* It uses JSON to serialize the function call payload
"""
import socket
import random, string
import hmac
import json
import threading

secret = "SECRET"

class RPCHandler:
    def __init__(self, secret):
        self._secret = secret
        self._register = {}

    def register_func(self, func):
        self._register[func.__name__] = func
        
    def handle_call(self, sock):
        keymsg = ''.join([random.choice(string.lowercase) for i in range(8)])
        sock.sendall(keymsg)
        hash = hmac.new(self._secret, keymsg)
        digest = hash.digest()
        response = sock.recv(512)
        if response != digest:
            sock.sendall("Authentication Failed!")
            sock.close()
        else:
            sock.sendall("Authenticated!")
            try:
                while True:
                    req = sock.recv(512)
                    d = json.loads(req)
                    funcname = d["name"]
                    args = d["args"]
                    kwargs = d["kwargs"]
                    print("Client calling %s(%s, %s)" % (funcname, args, kwargs))
                    try:
                        ret = self._register[funcname](*args, **kwargs)
                        sock.sendall(json.dumps({"ret": ret}))
                    except Exception as e:
                        sock.sendall(json.dumps({"exception": str(e)}))
            except EOFError:
                print("Closing RPC Handler...")


handler = RPCHandler(secret)

class RPCServer:
    def __init__(self, address):
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._sock.bind(address)

    def serve_forever(self):
        self._sock.listen(0)
        while True:
            client_sock,_ = self._sock.accept()
            thread = threading.Thread(target=handler.handle_call, args=(client_sock, ))
            thread.daemon = True
            thread.start()

class RPCProxy(object):
    def __init__(self, address, secret):
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._sock.connect(address)
        msg = self._sock.recv(512)
        h = hmac.new(secret, msg)
        self._sock.sendall(h.digest())
        print(self._sock.recv(512))

    def __getattr__(self, name):
        def proxy_func(*args, **kwargs):
            payload = {
                "name": name,
                "args": args,
                "kwargs": kwargs
            }
            self._sock.sendall(json.dumps(payload))
            result = json.loads(self._sock.recv(512))
            if "exception" in result:
                raise Exception(result['exception'])
            else:
                return result['ret']
        if name.startswith("_"):
            return super(RPCProxy, self).__getattr__(name)
        else:
            return proxy_func
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容