def recv_command(self): # receive: ENQ (1 byte) + commandcode (2) + length (4) try: start = b'' while len(start) < 7: data = self.sock.recv(7 - len(start)) if not data: raise ProtocolError('recv_command: connection broken') start += data if start[0:1] != ENQ: raise ProtocolError('recv_command: invalid command header') # it has a length... length, = LENGTH.unpack(start[3:]) buf = b'' while len(buf) < length: read = self.sock.recv(min(READ_BUFSIZE, length-len(buf))) if not read: raise ProtocolError('recv_command: connection broken') buf += read try: return self.serializer.deserialize_cmd( buf, code2command[start[1:3]]) except Exception as err: self.send_error_reply('invalid command or garbled data') raise ProtocolError('recv_command: invalid command or ' 'garbled data') except socket.error as err: raise ProtocolError('recv_command: connection broken (%s)' % err)
def recv_reply(self): # receive first byte + (possibly) length start = b'' while len(start) < 5: data = self.sock.recv(5 - len(start)) if not data: raise ProtocolError('connection broken') start += data if start == ACK: return True, None if start[0:1] not in (NAK, STX): raise ProtocolError('invalid response %r' % start) # it has a length... length, = LENGTH.unpack(start[1:]) buf = b'' while len(buf) < length: read = self.sock.recv(READ_BUFSIZE) if not read: raise ProtocolError('connection broken') buf += read if not self.serializer: self.serializer = self.determine_serializer(buf, start[0:1] == STX) # XXX: handle errors return self.serializer.deserialize_reply(buf, start[0:1] == STX)
def recv_event(self): # receive STX (1 byte) + eventcode (2) + nblobs(1) + length (4) start = b'' while len(start) < 8: data = self.event_sock.recv(8 - len(start)) if not data: raise ProtocolError('read: event connection broken') start += data if start[0:1] != STX: raise ProtocolError('wrong event header') nblobs = ord(start[3:4]) length, = LENGTH.unpack(start[4:]) got = 0 # read into a pre-allocated buffer to avoid copying lots of data # around several times buf = bytearray(length) buf_view = memoryview(buf) while got < length: read = self.event_sock.recv_into(buf_view[got:], length - got) if not read: raise ProtocolError('read: event connection broken') got += read # XXX: error handling event = code2event[start[1:3]] data = self.serializer.deserialize_event(buf, event) blobs = [self._recv_blob() for _ in range(nblobs)] return data + (blobs, )
def recv_reply(self): # receive first byte + (possibly) length start = b'' while len(start) < 5: data = self.sock.recv(5 - len(start)) if not data: raise ProtocolError('connection broken') start += data if start == ACK: return True, None if start[0:1] not in (NAK, STX): raise ProtocolError('invalid response %r' % start) # it has a length... length, = LENGTH.unpack(start[1:]) buf = b'' while len(buf) < length: read = self.sock.recv(READ_BUFSIZE) if not read: raise ProtocolError('connection broken') buf += read if not self.serializer: # determine serializer class automatically for serializercls in SERIALIZERS.values(): try: candidate = serializercls() candidate.deserialize_reply(buf, start[0:1] == STX) except Exception: continue self.serializer = candidate break else: # no serializer found raise ProtocolError('no serializer found for this connection') # XXX: handle errors return self.serializer.deserialize_reply(buf, start[0:1] == STX)
def recv_event(self): # receive STX (1 byte) + eventcode (2) + length (4) start = b'' while len(start) < 7: data = self.event_sock.recv(7 - len(start)) if not data: raise ProtocolError('read: event connection broken') start += data if start[0:1] != STX: raise ProtocolError('wrong event header') length, = LENGTH.unpack(start[3:]) got = 0 # read into a pre-allocated buffer to avoid copying lots of data # around several times buf = np.zeros(length, 'c') # Py3: replace with bytearray+memoryview while got < length: read = self.event_sock.recv_into(buf[got:], length - got) if not read: raise ProtocolError('read: event connection broken') got += read # XXX: error handling event = code2event[start[1:3]] # serialized or raw event data? if DAEMON_EVENTS[event][0]: data = self.serializer.deserialize_event(buf.tostring(), event) else: data = event, memory_buffer(buf) return data
def _recv_blob(self): start = b'' while len(start) < 4: data = self.event_sock.recv(4 - len(start)) if not data: raise ProtocolError('read: event connection broken') start += data length, = LENGTH.unpack(start) got = 0 buf = np.zeros(length, 'c') # Py3: replace with bytearray+memoryview while got < length: read = self.event_sock.recv_into(buf[got:], length - got) if not read: raise ProtocolError('read: event connection broken') got += read return buf