gpt4 book ai didi

Python unpickling 堆栈下溢

转载 作者:太空狗 更新时间:2023-10-29 23:59:01 61 4
gpt4 key购买 nike

我一直在开发一个 python 应用程序,其中客户端向服务器发送时钟信号,而服务器以音频信号响应。
我有两个按钮,一个用于启动时钟,一个用于暂停轨道。

主类

# function I call when I hit the play button
def play(self):
start_song = [250]
global IS_FIRST_PLAY
if IS_FIRST_PLAY:
IS_FIRST_PLAY = False
self.startClock()
if IS_CONNECTED:
client.sendMessage(start_song)

# here I start the clock and send a constant clock signal to the client
def startClock(self):
clock = midi.startClock()
for i in clock:
if IS_CONNECTED:
client.sendMessage(i)
midi.playing = True

# here I pause the track
def pause(self):
stop_song = [252]
if IS_CONNECTED:
client.sendMessage(stop_song)
midi.sendMidiMessage(stop_song)
midi.playing = False
midi.mtClock = [0, 0, 0, 0]

客户端类

# this is the client.sendMessage() function
def sendMessage(self, message):
self.s.sendall(pickle.dumps(message))

服务器类

# this is the class that handles the incoming clock signal for the server
class MyTCPHandler(socketserver.BaseRequestHandler):

def handle(self):
global IS_FIRST_PLAY, IS_PLAYING
thread1 = threading.Thread(target=self.sendAudio)
thread1.start()
while True:
# here throws python an error
self.data = pickle.loads(self.request.recv(12).strip())

这一切都很好,除了一个随机的时刻,当我改变暂停播放时,我不断收到这个错误:

Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/socketserver.py", line 306, in _handle_request_noblock
self.process_request(request, client_address)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/socketserver.py", line 332, in process_request
self.finish_request(request, client_address)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/socketserver.py", line 345, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/socketserver.py", line 666, in __init__
self.handle()
File "/Users/cedricgeerinckx/Dropbox/Redux/OSX/Server.py", line 85, in handle
self.data = pickle.loads(self.request.recv(12).strip())
_pickle.UnpicklingError: unpickling stack underflow

这个问题可能是什么?

最佳答案

unpickling 堆栈下溢 可能会在 pickle 意外结束时发生。

此处 self.request.recv(12),您最多只能接收 12 个字节,您的 pickle 对象必须超过 12 个字节,因此它会被截断。

我不建议直接处理 TCP 套接字,除非您非常非常熟悉网络并且需要非常高的性能。我建议使用 HTTP 来包装您的消息并使用 HTTP 库。

如果您确实必须直接处理 TCP,您将有两个选择:

  1. 您可以就客户端和服务器之间的终止符字符串达成一致,例如“\0”(空)字符;并且您的消息将使用此终止符字符串分隔。终止符字符串绝不能出现在消息正文中(否则您将不得不想出一种方法来转义正文中的终止符字符串);您还需要缓冲您的数据包,以便如果您的读取大小小于或大于您的对象并在终止符字符串上拆分消息,您可以接收整个消息。请注意,您还需要处理这样的情况:如果连续快速发送多条小消息,接收方可能会在单个 .recv() 中收到多条消息。

  2. 也许更简单的方法是将所有消息的长度作为它发送的前四个字节。接收方始终从流中读取四个字节开始,将其解码为整数,然后从流中读取那么多字节,即一条完整消息。

或者,如果发送方和接收方都在 Python 中,您可以重新设计您的程序以使用多处理队列。

我想说使用 HTTP 库作为您的传输协议(protocol)可能是最简单的,因为它会处理所有这些细节,以便为您分块消息,并且可以跨多种机器和技术使用。

关于Python unpickling 堆栈下溢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23964048/

61 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com