Improved TcpClient receive

This commit is contained in:
Lonami 2016-09-07 19:48:49 +02:00
parent 7abe53e063
commit e6706080ad
3 changed files with 23 additions and 8 deletions

View File

@ -9,7 +9,7 @@ if __name__ == '__main__':
else: else:
print('Loading interactive example...') print('Loading interactive example...')
# First, initialize our TelegramClient and connect # First, initialize our TelegramClient and connect
settings = load_settings() settings = load_settings()
client = TelegramClient(session_user_id=settings.get('session_name', 'anonymous'), client = TelegramClient(session_user_id=settings.get('session_name', 'anonymous'),

View File

@ -1,5 +1,6 @@
# Python rough implementation of a C# TCP client # Python rough implementation of a C# TCP client
import socket import socket
from utils import BinaryWriter
class TcpClient: class TcpClient:
@ -23,11 +24,12 @@ class TcpClient:
def read(self, buffer_size): def read(self, buffer_size):
"""Reads (receives) the specified bytes from the connected peer""" """Reads (receives) the specified bytes from the connected peer"""
# TODO improve (don't cast to list, use a mutable byte list instead or similar, see recv_into) with BinaryWriter() as writer:
result = [] while writer.written_count < buffer_size:
while len(result) < buffer_size: # When receiving from the socket, we may not receive all the data at once
left_data = buffer_size - len(result) # This is why we need to keep checking to make sure that we receive it all
partial = self.socket.recv(left_data) left_count = buffer_size - writer.written_count
result.extend(list(partial)) partial = self.socket.recv(left_count)
writer.write(partial)
return bytes(result) return writer.get_bytes()

View File

@ -14,6 +14,7 @@ class BinaryWriter:
self.stream = stream self.stream = stream
self.writer = BufferedWriter(self.stream) self.writer = BufferedWriter(self.stream)
self.written_count = 0
# region Writing # region Writing
@ -21,30 +22,37 @@ class BinaryWriter:
def write_byte(self, value): def write_byte(self, value):
"""Writes a single byte value""" """Writes a single byte value"""
self.writer.write(pack('B', value)) self.writer.write(pack('B', value))
self.written_count += 1
def write_int(self, value, signed=True): def write_int(self, value, signed=True):
"""Writes an integer value (4 bytes), which can or cannot be signed""" """Writes an integer value (4 bytes), which can or cannot be signed"""
self.writer.write(int.to_bytes(value, length=4, byteorder='little', signed=signed)) self.writer.write(int.to_bytes(value, length=4, byteorder='little', signed=signed))
self.written_count += 4
def write_long(self, value, signed=True): def write_long(self, value, signed=True):
"""Writes a long integer value (8 bytes), which can or cannot be signed""" """Writes a long integer value (8 bytes), which can or cannot be signed"""
self.writer.write(int.to_bytes(value, length=8, byteorder='little', signed=signed)) self.writer.write(int.to_bytes(value, length=8, byteorder='little', signed=signed))
self.written_count += 8
def write_float(self, value): def write_float(self, value):
"""Writes a floating point value (4 bytes)""" """Writes a floating point value (4 bytes)"""
self.writer.write(pack('<f', value)) self.writer.write(pack('<f', value))
self.written_count += 4
def write_double(self, value): def write_double(self, value):
"""Writes a floating point value (8 bytes)""" """Writes a floating point value (8 bytes)"""
self.writer.write(pack('<d', value)) self.writer.write(pack('<d', value))
self.written_count += 8
def write_large_int(self, value, bits, signed=True): def write_large_int(self, value, bits, signed=True):
"""Writes a n-bits long integer value""" """Writes a n-bits long integer value"""
self.writer.write(int.to_bytes(value, length=bits // 8, byteorder='little', signed=signed)) self.writer.write(int.to_bytes(value, length=bits // 8, byteorder='little', signed=signed))
self.written_count += bits // 8
def write(self, data): def write(self, data):
"""Writes the given bytes array""" """Writes the given bytes array"""
self.writer.write(data) self.writer.write(data)
self.written_count += len(data)
# endregion # endregion
@ -98,6 +106,11 @@ class BinaryWriter:
self.writer.flush() self.writer.flush()
return self.stream.getvalue() return self.stream.getvalue()
def get_written_bytes_count(self):
"""Gets the count of bytes written in the buffer.
This may NOT be equal to the stream length if one was provided when initializing the writer"""
return self.written_count
# with block # with block
def __enter__(self): def __enter__(self):
return self return self