示例#1
0
    def run(self) -> None:
        try:
            self._socket_connection.setsockopt(socket.SOL_SOCKET,
                                               socket.SO_REUSEADDR, 1)
            self._socket_connection.bind(self._address)
            logger.info(
                f"Server is now listening on: {self._address[0]}:{self._address[1]}"
            )
            self._socket_connection.listen(4)
        except OSError as e:
            # [WinError 10038] socket closed before
            logger.error(e)
            self._exit.set()
        except socket.gaierror:
            raise ValueError(
                f"Address error. {self._address} is not a valid address. Address must be of type {SocketAddress}"
            )

        while not self._exit.is_set():
            try:
                (connection, addr) = self._socket_connection.accept()
                logger.info("New client connected: (%s)", str(addr))
                client_id = self._produce_next_client_id()
                client_communicator_id = to_server_id(client_id)
                client = self._client_communicator(
                    client_communicator_id, self._address, connection,
                    self._remove_disconnected_client)
                self._add_client(client_communicator_id, client)
            except OSError as e:
                if not isinstance(e, socket.timeout):
                    if not self._exit.is_set():
                        logger.error("TCP connection closed while listening")
    def _connect(self, seconds_till_next_try: float = 2, timeout: float = -1) -> bool:
        waited = 0
        while not self._exit.is_set() and not self._is_connected:
            # TODO: Get timeout time from Connector.connect
            try:
                self._socket_connection = socket.create_connection(self._address)
                self._socket_connection.settimeout(self._recv_timeout)
                self._is_connected = True
                logger.info(f"Successfully connected to: {str(self._address)}")
                return True
            except ConnectionRefusedError:
                logger.warning("Could not connect to server with address: (%s)", str(self._address))
            except OSError as e:
                logger.error("Is already connected to server")
                logger.debug(e)
                self._is_connected = True
            except socket.gaierror:
                raise ValueError(
                    f"Address error. {self._address} is not a valid address. Address must be of type {SocketAddress}")

            self._exit.wait(seconds_till_next_try)
            waited += seconds_till_next_try
            if waited > timeout >= 0:
                logger.warning("Connection timeout")
                return False
        return False
    def _recv_data(self, plain_byte_stream: ByteStream, encrypted_byte_stream: ByteStream) -> \
            Optional[bytes]:
        """Returns every chunk, that can be decrypted"""
        data = plain_byte_stream.next_all_bytes()
        plain_byte_stream.remove_consumed_bytes()
        if len(data) > 0:
            return data
        encrypted_data = encrypted_byte_stream.next_all_bytes()
        encrypted_byte_stream.remove_consumed_bytes()
        try:
            while not self._exit.is_set():
                chunk_data = self._socket_connection.recv(self.CHUNK_SIZE)
                if chunk_data == b"":
                    logger.info("Connection reset, (%s)", str(self._address))
                    self._is_connected = False
                    return None
                else:
                    if not self.cryptographer.is_encrypted_communication:
                        return chunk_data
                    if b"%%" in chunk_data:
                        corresponding_data = chunk_data.split(b"%%")[0]
                        encrypted_data += corresponding_data
                        encrypted_byte_stream += chunk_data[len(corresponding_data) + 2:]
                        data += self.cryptographer.decrypt(encrypted_data)
                        return data
                    else:
                        encrypted_data += chunk_data

        except ConnectionResetError:
            if not self._exit.is_set():
                logger.warning(f"Connection reset at ID({self._id}), {self._address}")
            self._is_connected = False

        except ConnectionAbortedError:
            if not self._exit.is_set():
                logger.warning(f"Connection aborted at ID({self._id}), {self._address}")
            self._is_connected = False

        except OSError as e:
            if not isinstance(e, socket.timeout):
                if not self._exit.is_set():
                    logger.warning("TCP connection closed while listening")
                self._is_connected = False
 def stop(self, is_same_thread=False) -> None:
     """Stops all listening and the thread is joined. Send processes are not stopped and it the thread first
     stops when all data is sent."""
     if self._closed:
         logger.debug("Prevented closing already closed communicator")
     else:
         communicator_side = "Client" if self._id >= CLIENT_ID_START else "Server"
         logger.info(f"Stopping {communicator_side}side communicator: {self._id}")
         self._exit.set()
         if self._socket_connection is not None:
             self._socket_connection.close()
         self._is_connected = False
         if not is_same_thread:
             self.join()
         remove_manager(self._id)
         if self._on_close is not None:
             try:
                 self._on_close(self)
             except TypeError:
                 pass  # no function provided
         self._closed = True
示例#5
0
 def stop_listening(self) -> None:
     self._exit.set()
     self._socket_connection.close()
     self.join()
     logger.info("Closed server listener")