def write(self, string): """ Write given bytes string to socket. Loop as long as every byte in string is written unless exception is raised. """ try: self.sock.sendall(string) except SOCKET_TIMEOUT as error: raise ConnectionError('Socket timed out. ' + str(error)) except SOCKET_ERROR as error: raise ConnectionError('Failed to write to socket. ' + str(error))
def read(self, length): """ Read as many bytes from socket as specified in length. Loop as long as every byte is read unless exception is raised. """ try: data = self.sock.recv(length) if not data: raise ConnectionError('Connection unexpectedly closed.') return data except SOCKET_TIMEOUT as error: raise ConnectionError('Socket timed out. ' + str(error)) except SOCKET_ERROR as error: raise ConnectionError('Failed to read from socket. ' + str(error))
def decodeLength(length): """ Decode length based on given bytes. :param length: Bytes string to decode. :return: Decoded length. """ bytes_length = len(length) if bytes_length < 2: offset = b'\x00\x00\x00' XOR = 0 elif bytes_length < 3: offset = b'\x00\x00' XOR = 0x8000 elif bytes_length < 4: offset = b'\x00' XOR = 0xC00000 elif bytes_length < 5: offset = b'' XOR = 0xE0000000 else: raise ConnectionError('Unable to decode length of {}'.format(length)) decoded = unpack('!I', (offset + length))[0] decoded ^= XOR return decoded
def create_transport(host, **kwargs): try: sock = create_connection((host, kwargs['port']), kwargs['timeout'], (kwargs['saddr'], 0)) except (SOCKET_ERROR, SOCKET_TIMEOUT) as error: raise ConnectionError(error) return SocketTransport(sock=sock)
def read(self, length): """ Read as many bytes from socket as specified in length. Loop as long as every byte is read unless exception is raised. """ data = bytearray() while len(data) != length: data += self.sock.recv((length - len(data))) if not data: raise ConnectionError('Connection unexpectedly closed.') return data
def read(self, length): """ Read as many bytes from socket as specified in length. Loop as long as every byte is read unless exception is raised. """ try: data = b'' while len(data) < length: rlist, wlist, xlist = select.select([self.sock], [], [self.sock], 5) if rlist: data += self.sock.recv(length - len(data)) elif xlist: raise ConnectionError('Connection unexpectedly closed.') else: raise ConnectionError('Connection read timeout.') return data except SOCKET_TIMEOUT as error: raise ConnectionError('Socket timed out. ' + str(error)) except SOCKET_ERROR as error: raise ConnectionError('Failed to read from socket. ' + str(error))
def determineLength(length): """ Given first read byte, determine how many more bytes needs to be known in order to get fully encoded length. :param length: First read byte. :return: How many bytes to read. """ integer = ord(length) if integer < 128: return 0 elif integer < 192: return 1 elif integer < 224: return 2 elif integer < 240: return 3 else: raise ConnectionError('Unknown controll byte {}'.format(length))
def encodeLength(length): """ Encode given length in mikrotik format. :param length: Integer < 268435456. :returns: Encoded length. """ if length < 128: ored_length = length offset = -1 elif length < 16384: ored_length = length | 0x8000 offset = -2 elif length < 2097152: ored_length = length | 0xC00000 offset = -3 elif length < 268435456: ored_length = length | 0xE0000000 offset = -4 else: raise ConnectionError('Unable to encode length of {}'.format(length)) return pack('!I', ored_length)[offset:]