Python Stack Overflow

I was working on a python application where the client sends a synchronization signal to the server and the server responds with a beep.
I have two buttons: one to start the clock and one to pause the track.

Main class

# 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] 

Customer class

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

Server class

 # 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()) 

Everything works fine, except for the occasional moment when I change the pause to play, I keep getting this error:

 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 

What could be this problem?

+6
source share
1 answer

unpickling stack underflow can occur when a splinter unexpectedly ends.

Here self.request.recv(12) you get a maximum of 12 bytes, your pickled object should be longer than 12 bytes, and therefore it is cropped.

I would not recommend accessing TCP sockets directly if you are not very familiar with networks and you need very high performance. I would suggest using HTTP to transport your messages and use the HTTP library.

If you really need to deal with TCP directly, you will have two options:

  • You can match the terminator string between your client and server, for example, the character "\ 0" (zero); and your posts will be limited to this terminator string. The terminator string should never occur inside the body of the message (or you will need to figure out a way to exit the terminator string in the body); you will also need to buffer your packets so that you can receive the entire message if your reading size is less than or larger than your objects and split the messages into a terminator string. Please note that you will also need to handle a situation where when sending several small messages, the recipient can receive several messages in one .recv() .

  • It may be easier to start all messages along its length, like the first four bytes that it sends. The receiver will always start by reading four bytes from the stream, decoding it into an integer, and reading that many bytes from the stream, that one complete message.

Alternatively, you can rebuild your program to use the multiprocessing queue if both the sender and receiver are in Python.

I would say using the HTTP library, since your transport protocol will probably be the easiest, since it will handle all these details to send messages to you, and can also be used on several machines and technologies.

+4
source

Source: https://habr.com/ru/post/970113/


All Articles