예제 #1
0
class Server:
    def __init__(self, address, port, max_connections):
        self.socket = Socket()
        self.address = address
        self.port = port
        self.connections = max_connections

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.socket.__exit__(exc_type, exc_val, exc_tb)
        logging.info('Server closed')

    def start(self):
        logging.info('Starting server')
        try:
            self.socket.bind((self.address, self.port))
        except OSError:
            logging.debug("Address already taken - {address}:{port}".format(
                address=self.address, port=self.port))
            exit(1)
        self.socket.listen(self.connections)
        logging.info('Server has been started. Waiting for connections.')

    def close(self):
        self.socket.close()

    def accept(self):
        client_sock, client_addr = self.socket.accept()
        return client_sock, client_addr
예제 #2
0
class Client:
    def __init__(self, address, port, buffer_size):
        self.socket = Socket()
        self.address = address
        self.port = port
        self.buffer_size = buffer_size

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.socket.__exit__()
        logging.info('Client closed')

    def connect(self):
        logging.info('Starting client')
        try:
            self.socket.connect((self.address, self.port))
            logging.info('Connected to {server}:{port}'.format(server=self.address, port=self.port))
        except ConnectionRefusedError:
            logging.warning('Failed to connect.')
            logging.exception('Exception: ')
            exit(1)

    def send(self, payload, flags=0):
        """
        Send message(payload) to socket. Appends 8 bytes with information of message length to the beginning.
        """
        total_sent = 0
        send_bytes = len(payload).to_bytes(8, byteorder='little') + payload

        while total_sent < len(send_bytes):
            try:
                sent = self.socket.send(send_bytes[total_sent:])
            except ConnectionResetError:
                logging.warning("Connection aborted.")
                logging.exception("Exception:")
                exit(1)
            if sent == 0:
                raise RuntimeError("Connection broken")
            total_sent += sent

    def receive(self):
        """
        Receive data by chunks of buffer size.
        :return: full message without leading 8 bytes (message length)
        """
        message = self.socket.recv(self.buffer_size)

        if len(message) < self.buffer_size:
            return message[8:]  # First 8 bytes contains payload size

        else:
            chunks = []
            payload_size, payload = int.from_bytes(message[0:8], byteorder='little'), message[8:]
            chunks.append(payload)
            bytes_received = len(payload)

            while bytes_received < payload_size:
                chunk = self.socket.recv(min(payload_size - bytes_received, self.buffer_size))
                if chunk == b'':
                    raise RuntimeError("Socket connection broken")
                chunks.append(chunk)
                bytes_received += len(chunk)

            return b''.join(chunks)

    def ask_for_task(self):
        return self.send_pickled({'Command': "NewTask"})

    def receive_unpickled(self):
        return pickle.loads(self.receive())

    def send_pickled(self, bytes):
        return self.send(pickle.dumps(bytes))