From 0e06ed96afa6960b4095b792335a334f3cde6960 Mon Sep 17 00:00:00 2001 From: Simon Lindholm Date: Mon, 22 Jan 2018 23:36:45 +0100 Subject: [PATCH] Do manual line buffering in Python --- battlecode-manager/server.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/battlecode-manager/server.py b/battlecode-manager/server.py index 61011bf..59455a6 100644 --- a/battlecode-manager/server.py +++ b/battlecode-manager/server.py @@ -340,8 +340,26 @@ def __init__(self, *args, **kwargs): self.error = "" self.logged_in = False self.is_unix_stream = is_unix_stream + self.buffer_small = b'' + self.buffer_large = [] + super(ReceiveHandler, self).__init__(*args, **kwargs) + def read_line(self): + while True: + if self.buffer_small: + pos = self.buffer_small.find(b'\n') + if pos != -1: + ret = b''.join(self.buffer_large) + self.buffer_small[:pos] + self.buffer_small = self.buffer_small[pos+1:] + self.buffer_large = [] + return ret + else: + self.buffer_large.append(self.buffer_small) + self.buffer_small = self.request.recv(4096) + if not self.buffer_small: + raise IOError("reached socket EOF before finding newline") + def get_next_message(self) -> object: ''' Returns the json loaded object of the next string that is sent over the @@ -355,16 +373,14 @@ def get_next_message(self) -> object: recv_socket = self.request game = self.game - wrapped_socket = recv_socket.makefile('rwb', 1) logging.debug("Client %s: Waiting for next message", self.client_id) try: - data = next(wrapped_socket) + data = self.read_line() except (StopIteration, IOError): print("{} has not sent message for {} seconds, assuming they're dead".format( self.game.get_player(self.client_id)['player'], TIMEOUT )) - wrapped_socket.close() recv_socket.close() if bc.Team.Red == self.game.get_player(self.client_id)['player'].team: self.game.winner = 'player2' @@ -377,7 +393,6 @@ def get_next_message(self) -> object: self.game.game_over = True raise TimeoutError() except KeyboardInterrupt: - wrapped_socket.close() recv_socket.close() if bc.Team.Red == self.game.get_player(self.client_id)['player'].team: self.game.winner = 'player2' @@ -389,8 +404,6 @@ def get_next_message(self) -> object: self.game.disconnected = True self.game.game_over = True raise KeyboardInterrupt() - finally: - wrapped_socket.close() data = data.decode("utf-8").strip() return data @@ -420,11 +433,9 @@ def send_message(self, obj: object) -> None: logging.debug("Client %s: Sending message %s", self.client_id, encoded_message) - wrapped_socket = send_socket.makefile('rwb', 1) try: - wrapped_socket.write(encoded_message) + self.request.sendall(encoded_message) except IOError: - wrapped_socket.close() send_socket.close() print("{} has not accepted message for {} seconds, assuming they're dead".format( [p for p in self.game.players if p['id'] == self.client_id][0]['player'], @@ -441,7 +452,6 @@ def send_message(self, obj: object) -> None: self.game.game_over = True raise TimeoutError() except KeyboardInterrupt: - wrapped_socket.close() send_socket.close() if bc.Team.Red == self.game.get_player(self.client_id)['player'].team: self.game.winner = 'player2' @@ -453,8 +463,6 @@ def send_message(self, obj: object) -> None: self.game.disconnected = True self.game.game_over = True raise KeyboardInterrupt() - finally: - wrapped_socket.close() return def message(self, state_diff):