def CheckDataReceived(self): """Tries to extract a Message from the data buffer and process it.""" currentLength = len(self.buffer_in) if currentLength < 24: return # Extract the message header from the buffer, and return if not enough # buffer to fully deserialize the message object. try: # Construct message mstart = self.buffer_in[:24] ms = StreamManager.GetStream(mstart) reader = BinaryReader(ms) m = Message() # Extract message metadata m.Magic = reader.ReadUInt32() m.Command = reader.ReadFixedString(12).decode('utf-8') m.Length = reader.ReadUInt32() m.Checksum = reader.ReadUInt32() # Return if not enough buffer to fully deserialize object. messageExpectedLength = 24 + m.Length # percentcomplete = int(100 * (currentLength / messageExpectedLength)) # self.Log("Receiving %s data: %s percent complete" % (m.Command, percentcomplete)) if currentLength < messageExpectedLength: return except Exception as e: self.Log('Error: Could not read initial bytes %s ' % e) return finally: StreamManager.ReleaseStream(ms) del reader # The message header was successfully extracted, and we have enough enough buffer # to extract the full payload try: # Extract message bytes from buffer and truncate buffer mdata = self.buffer_in[:messageExpectedLength] self.buffer_in = self.buffer_in[messageExpectedLength:] # Deserialize message with payload stream = StreamManager.GetStream(mdata) reader = BinaryReader(stream) message = Message() message.Deserialize(reader) # Propagate new message self.MessageReceived(message) except Exception as e: self.Log('Error: Could not extract message: %s ' % e) return finally: StreamManager.ReleaseStream(stream) # Finally, after a message has been fully deserialized and propagated, # check if another message can be extracted with the current buffer: if len(self.buffer_in) >= 24: self.CheckDataReceived()
def CheckDataReceived(self): """Tries to extract a Message from the data buffer and process it.""" currentLength = len(self.buffer_in) if currentLength < 24: return False # Extract the message header from the buffer, and return if not enough # buffer to fully deserialize the message object. try: # Construct message mstart = self.buffer_in[:24] ms = StreamManager.GetStream(mstart) reader = BinaryReader(ms) m = Message() # Extract message metadata m.Magic = reader.ReadUInt32() m.Command = reader.ReadFixedString(12).decode('utf-8') m.Length = reader.ReadUInt32() m.Checksum = reader.ReadUInt32() # Return if not enough buffer to fully deserialize object. messageExpectedLength = 24 + m.Length if currentLength < messageExpectedLength: return False except Exception as e: logger.debug( f"{self.prefix} Error: could not read message header from stream {e}" ) # self.Log('Error: Could not read initial bytes %s ' % e) return False finally: StreamManager.ReleaseStream(ms) del reader # The message header was successfully extracted, and we have enough enough buffer # to extract the full payload try: # Extract message bytes from buffer and truncate buffer mdata = self.buffer_in[:messageExpectedLength] self.buffer_in = self.buffer_in[messageExpectedLength:] # Deserialize message with payload stream = StreamManager.GetStream(mdata) reader = BinaryReader(stream) message = Message() message.Deserialize(reader) if self.incoming_client and self.expect_verack_next: if message.Command != 'verack': self.Disconnect("Expected 'verack' got {}".format( message.Command)) # Propagate new message self.MessageReceived(message) except Exception as e: logger.debug(f"{self.prefix} Could not extract message {e}") # self.Log('Error: Could not extract message: %s ' % e) return False finally: StreamManager.ReleaseStream(stream) return True