diff --git a/protocoin/clients.py b/protocoin/clients.py index 8f10e67..2af7591 100644 --- a/protocoin/clients.py +++ b/protocoin/clients.py @@ -1,4 +1,4 @@ -from cStringIO import StringIO +from io import BytesIO from .serializers import * from .exceptions import NodeDisconnectException import os @@ -15,7 +15,7 @@ class BitcoinBasicClient(object): def __init__(self, socket): self.socket = socket - self.buffer = StringIO() + self.buffer = BytesIO() def close_stream(self): """This method will close the socket stream.""" @@ -52,7 +52,7 @@ def receive_message(self): return # Go to the beginning of the buffer - self.buffer.reset() + self.buffer.seek(0) message_model = None message_header_serial = MessageHeaderSerializer() @@ -66,7 +66,9 @@ def receive_message(self): return payload = self.buffer.read(message_header.length) - self.buffer = StringIO() + buffer = BytesIO() + buffer.write(self.buffer.read()) + self.buffer = buffer self.handle_message_header(message_header, payload) payload_checksum = \ @@ -78,7 +80,7 @@ def receive_message(self): if message_header.command in MESSAGE_MAPPING: deserializer = MESSAGE_MAPPING[message_header.command]() - message_model = deserializer.deserialize(StringIO(payload)) + message_model = deserializer.deserialize(BytesIO(payload)) return (message_header, message_model) @@ -89,7 +91,7 @@ def send_message(self, message): :param message: The message object to send """ - bin_data = StringIO() + bin_data = BytesIO() message_header = MessageHeader(self.coin) message_header_serial = MessageHeaderSerializer() @@ -118,21 +120,22 @@ def loop(self): raise NodeDisconnectException("Node disconnected.") self.buffer.write(data) - data = self.receive_message() - - # Check if the message is still incomplete to parse - if data is None: - continue - - # Check for the header and message - message_header, message = data - if not message: - continue - - handle_func_name = "handle_" + message_header.command - handle_func = getattr(self, handle_func_name, None) - if handle_func: - handle_func(message_header, message) + while True: + data = self.receive_message() + + # Check if the message is still incomplete to parse + if data is None: + break + + # Check for the header and message + message_header, message = data + if not message: + continue + + handle_func_name = "handle_" + message_header.command + handle_func = getattr(self, handle_func_name, None) + if handle_func: + handle_func(message_header, message) class BitcoinClient(BitcoinBasicClient): """This class implements all the protocol rules needed diff --git a/protocoin/fields.py b/protocoin/fields.py index 14547cf..c8b0a0c 100644 --- a/protocoin/fields.py +++ b/protocoin/fields.py @@ -1,6 +1,6 @@ from .exceptions import NodeDisconnectException -from cStringIO import StringIO +from io import BytesIO import struct import time import random @@ -157,12 +157,11 @@ def parse(self, value): def deserialize(self, stream): data = stream.read(self.length) - return data.split("\x00", 1)[0] + return data[:(data+b'\x00').index(b'\x00')].decode("utf-8") def serialize(self): - bin_data = StringIO() - bin_data.write(self.value[:self.length]) - bin_data.write("\x00" * (12 - len(self.value))) + bin_data = BytesIO() + bin_data.write(struct.pack("12s", self.value.encode("utf-8"))) return bin_data.getvalue() class NestedField(Field): @@ -211,7 +210,7 @@ def parse(self, value): self.value = value def serialize(self): - bin_data = StringIO() + bin_data = BytesIO() self.var_int.parse(len(self)) bin_data.write(self.var_int.serialize()) serializer = self.serializer_class() @@ -223,7 +222,7 @@ def deserialize(self, stream): count = self.var_int.deserialize(stream) items = [] serializer = self.serializer_class() - for i in xrange(count): + for i in range(count): data = serializer.deserialize(stream) items.append(data) return items @@ -236,7 +235,7 @@ def __len__(self): class IPv4AddressField(Field): """An IPv4 address field without timestamp and reserved IPv6 space.""" - reserved = "\x00"*10 + "\xff"*2 + reserved = b"\x00"*10 + b"\xff"*2 def parse(self, value): self.value = value @@ -247,7 +246,7 @@ def deserialize(self, stream): return socket.inet_ntoa(addr) def serialize(self): - bin_data = StringIO() + bin_data = BytesIO() bin_data.write(self.reserved) bin_data.write(socket.inet_aton(self.value)) return bin_data.getvalue() @@ -273,12 +272,12 @@ def deserialize(self, stream): def serialize(self): if self.value < 0xFD: - return chr(self.value) + return struct.pack("B", self.value) if self.value <= 0xFFFF: - return chr(0xFD) + struct.pack("