python - pickle.loads() 的问题 - 输入不足
问题描述
我正在尝试制作一个小型多人游戏,因此需要发送对象。已经创建了服务器和客户端,一切都在发送字节,例如(str("").encode(utf-8))
。
但是当我尝试使用泡菜时,我开始遇到问题。我在下面犯了任何错误吗?
服务器.py:
import socket
import threading
import pickle
HEADER = 8 #Contains info about incoming msg SIZE! first 8 bytes contains size
FORMAT = "utf-8"
PORT = 5558
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
DISCONNECT_MSG = "!Disconnect"
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(ADDR)
def handle_client(client_socket, client_addr):
print(f"[NEW CONNECTION] {client_addr} connected!")
while True:
try:
msg = pickle.loads(client_socket.recv(2048))
print(f"[RECEIVED] {client_addr} - {msg}")
if msg == DISCONNECT_MSG:
print(f"[DISCONNECTED] client {client_addr} has disconnected")
client_socket.close()
return False
except socket.error as e:
print(e)
def start_server(server):
server.listen()
print("[STARTED] server is online!")
while True:
client_socket, client_addr = server.accept()
thread = threading.Thread(target=handle_client, args=(client_socket, client_addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
print("[STARTING] server is starting...")
start_server(server_socket)
客户端.py
import socket
import pickle
HEADER = 8
FORMAT = "utf-8"
PORT = 5558
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
DISCONNECT_MSG = "!Disconnect"
class Client:
def __init__(self):
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def connect_to_server(self, server_address):
"""
:param server_address: tuple(IP, PORT)
:return:
"""
self.get_client_socket().connect(server_address)
def get_client_socket(self):
return self.client_socket
def send_object(self, object):
msg = pickle.dumps(object)
self.get_client_socket().sendall(msg)
client = Client()
client.connect_to_server(ADDR)
d = "1"
client.send_object(d)
#client.send_object(DISCONNECT_MSG)
我也尝试将 while 循环放入 send_object() 但在成功接收几次后我得到:
msg = pickle.loads(client_socket.recv(2048))
_pickle.UnpicklingError: invalid load key, '\x00'.
解决方案
经过一些研究,似乎在尝试解开对象之前,您首先需要检查收到的消息是否不是 None。因为服务器不断尝试从客户端接收消息,但这是另一个问题。server.py 中的代码修改:
def handle_client(client_socket, client_addr):
print(f"[NEW CONNECTION] {client_addr} connected!")
while True:
try:
msg = client_socket.recv(2048)
if msg:
new_msg = pickle.loads(msg[HEADER:])
print(f"[RECEIVED] {client_addr} - {new_msg}")
if msg == DISCONNECT_MSG:
print(f"[DISCONNECTED] client {client_addr} has disconnected")
client_socket.close()
return False
except socket.error as e:
print(e)
注意 -> 直到 DISCONNECT 消息没有从客户端发送,它将使用很多处理器时间(上面提到的问题)
推荐阅读
- amazon-web-services - 如何在 Terraform 中输出一种类型的所有资源?
- javascript - 拖动时谷歌地图全屏偏移街景小人
- scala - 不使用括号调用带参数的方法
- c# - OpenID 与 ASP.NET MVC 连接
- angular - Angular 6 PWA / SyntaxError: Unexpected token / in JSON at position 0
- solr - Solr AutoScaling - 在新节点上添加副本
- julia - 将 x.xxxxxxe-x*10^xx 形式的两个数字相乘不能正常工作
- ios - Concat 运算符 RxSwift
- python - 检测列表中引用的单词
- microsoft-graph-api - 带有 Outlook 资源(消息、事件、联系人)的 MS 图形 api 架构扩展过滤器错误