简介
python实现简单的服务器和客户端实现,主要使用了struct、json、socket库。属于【深入理解RPC】基于Python自建分布式高并发RPC服务的练习文章小结
正题
交互规则
# 业务交互输入和输出(客户端和服务)
# 采用协议头长度划分业务
# | head(4byte) | data(...) |
# {
# "in" : "ping"
# "params" : "hello"
# }
#
# {
# "out" : "pong"
# "params" : "world"
# }
客户端
import json
import socket
import struct
def rpc(sock, handlers, handle):
handlers[handle](sock)
def ping(sock):
body = json.dumps({'in':'ping', 'params':'hello'})
lenght_prefix = struct.pack('I', len(body))
print(body, lenght_prefix)
sock.sendall(lenght_prefix)
sock.sendall(body.encode())
#等待回复
lenght_prefix = sock.recv(4)
(length,) = struct.unpack('I', lenght_prefix)
data = sock.recv(length)
print(length, data)
if __name__ == '__main__':
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect(('localhost', 8080))
handlers = {
'ping': ping
}
rpc(sock, handlers, 'ping')
服务端
import json
import socket
import struct
def socket_connect(conn, addr, handlers, maps):
with conn:
print('connect :', addr)
length_prefix = conn.recv(4)
print(length_prefix)
(length,) = struct.unpack('I', length_prefix)
data = conn.recv(length)
print(data)
response = json.loads(data)
handlers[maps[response['in']]](conn)
def pong(conn):
# 回复
body = json.dumps({'out': 'pong', 'params': 'world'})
length_prefix = struct.pack('I', len(body))
conn.sendall(length_prefix)
conn.sendall(body.encode())
if __name__ == '__main__':
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.bind(('localhost', 8080))
print('begin!')
sock.listen(1)
conn, addr = sock.accept()
handlers = { #调用函数表
'pong': pong
}
maps = { #客户端与服务操作映射表
'ping' : 'pong'
}
socket_connect(conn, addr, handlers, maps)
通讯效果如下