Example #1
0
 def __init__(self, host, port):
     self._host = host
     self._port = port
     self._socket_list = []
     
     self._logger = logging.getLogger('CluelessServer')
     
     self._output_queue = Queue.Queue()
     
     self._server_message = ServerMessage(self._output_queue)
Example #2
0
class CluelessServer:
    __connection_backlog = 10
    __select_timeout = 0.5
    __read_size = 4096

    def __init__(self, host, port):
        self._host = host
        self._port = port
        self._socket_list = []
        
        self._logger = logging.getLogger('CluelessServer')
        
        self._output_queue = Queue.Queue()
        
        self._server_message = ServerMessage(self._output_queue)
    
    # Starts the server
    def start_server(self):
        # Create the server socket
        self._logger.debug('Creating server socket.')
        self._server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        
        # Listen for connections
        self._logger.debug('Listening for connections.')
        self._server_socket.bind((self._host, self._port))
        self._server_socket.listen(self.__connection_backlog)
        
        self._socket_list.append(self._server_socket)
        
        server_thread = threading.Thread(target=self.run)
        server_thread.start()
    
    def run(self):
        while True:
            ready_to_read, ready_to_write, input_error = select.select(self._socket_list, [], [], self.__select_timeout)
            
            # Loop through list of sockets that have data
            for sock in ready_to_read:
                # Received new connection request
                if sock == self._server_socket:
                    # Accept the connection and append it to the socket list
                    self._logger.debug('Received connection request. Establishing connection with client.')
                    new_sock, address = self._server_socket.accept()
                    new_sock.settimeout(0.5)  #TODO: Remove this and while loop below if we start running into issues (workaround for while loop timeout-blocking issue)
                    
                    # Check the number of players currently connected to the server
                    if len(self._socket_list) < 7:
                        self._logger.debug('Client connected from %s on port %s' % address)
                        
                        # Add the socket to the socket list
                        self._socket_list.append(new_sock)
                        
                        # Add a new player to the server model
                        self._server_message.add_player(address)
                        
                        # Send all messages in the output queue
                        self.send_all_messages(new_sock)
                    # Game is full
                    else:
                        self._logger.debug('Closed connection with %s on port %s' % address)
                        
                        new_sock.close()
                # Received message from client
                else:
                    # This should ensure all the data from the socket is received
                    message_list = []
                    
                    while 1:
                        message, bytes_read = MessageProtocol.recv_msg(sock)
                        
                        if bytes_read > 0:
                            message_list.append(message)
                        else:
                            break

                    # Check to see if data is available
                    message_list_length = len(message_list)
                    
                    if message_list_length > 0:
                        # Retrieve the player associated with this socket
                        address = sock._sock.getpeername()
                        player = self._server_message.get_player(address)
                        
                        # Handle the request
                        self._server_message.handle_message(message_list, player)
                        
                        # Send response to the client(s)
                        self._logger.debug('Sending message(s) to client(s).')
                        
                        # Send all messages in the output queue
                        self.send_all_messages(sock)
                    # Client disconnected
                    else:
                        self._logger.error('Client disconnected.')
                        self.remove_client(sock)
        
        self._server_socket.close()
    
    # Send all of the messages in the output queue
    def send_all_messages(self, sock):
        while self._output_queue.qsize() > 0:
            broadcast, message = self._output_queue.get()
            
            self.send_message(broadcast, sock, message)
    
    # Sends a reply message or broadcasts the message to all clients
    def send_message(self, broadcast, sock, message):
        # Check to see if this is a broadcast message
        if broadcast == True:
            for client_socket in self._socket_list:
                if client_socket != self._server_socket:
                    MessageProtocol.send_msg(client_socket, message)
        # Send the message to the specified socket (sock)
        else:
            MessageProtocol.send_msg(sock, message)
    
    # Remove the specified client from the server
    def remove_client(self, sock):
        address = sock._sock.getpeername()
        self._logger.debug('Removing the connection to (%s, %s).' % address)
        
        self._socket_list.remove(sock)
        self._server_message.remove_player(address)
        
        sock.close()