Вопрос: Взаимодействие двух хостов в сетевой игре?

Лучший ответ:
Доброго времени суток, в принципе 66demon666 правильно мыслил, но, к сожалению, не рассказал про практическую сторону. Я предлагаю вам воспользоваться более высокоуровневым стандартным модулем Python "socketserver", который позволяет проще реализовать сервера, которые работают по протоколам UDP и TCP. И так, говоря о настройке сервера, то нам понадобится изначально создать обработчик запросов, класс, который будет наследовать от класса "socketserver.BaseRequestHandler". В нашем новосозданном классе мы должны переопределить метод "handle", который по умолчанию ничего не делает, чтобы мы могли обрабатывать приходящие запросы. Далее мы создаём класс нашего сервера со множественным наследованием, в котором на данном этапе мы не добавим своих методов и не переопределим имеющиеся. Далее я уже пойду немного глубже и расскажу немного про своё мнение об организации игрового процесса. Я предлагаю пока что создать два класса: "Player" и "Session". "Session" будет наследовать наш TCP сервер и в своём "__init__" методе будет присваивать обработчику событий себя, чтобы мы из него могли спокойно оперировать данными сессии. Собственно, класс "Player" был добавлен с целью упрощения работы с данными игроков, дабы не создавать словари с их данными и прочее. В принципе, полагаю, на этом мои разъяснения закончены, остальное вы увидите в коде.import socket
import threading
import socketserver

class Player:
    def __init__(self, id, name):
        self.id = id
        self.name = name

class TCPRequestHandler(socketserver.BaseRequestHandler):
    def handle(self):
        encoding = "utf-8"

        data = self.request.recv(1024)

        # Дальше мы обрабатываем данные, которые пришли и, например, создаём из них словарь
        if len(session.get_players()) < 2:
            player = Player(data["id"], data["name"])
            session.add_player(player)
            self.request.send("Some response".encode(encoding))
        else:
            self.request.send("Some error data".encode(encoding))

class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass

class Session(ThreadedTCPServer):
    def __init__(self, connection_data, request_handler):
        super().__init__(connection_data, request_handler)

        self.max_players = 2
        self.players = {}
        self.over = False

        request_handler.session = self

    def get_players(self):
        return self.players

    def add_player(self, player):
        if type(player) == Player:
            if len(self.players) < self.max_players:
                self.players[player.id] = player
            else:
                raise Exception("Players overflow")
        else:
            raise TypeError("'player' argument must be a 'Player' type")

    def game_over(self):
        self.over = True

if __name__ == "__main__":
    HOST, PORT = "localhost", 80

    session = Session((HOST, PORT), TCPRequestHandler)

    with session:
        session_thread = threading.Thread(target=session.serve_forever)

        session_thread.daemon = True
        session_thread.start()

        while not session.over:
            pass # Заглушка, чтобы сервер работал

        session.shutdown()

Худший ответ:
Ну так а как-же, все в одном потоке делается, пока не завершиться одна операция, другая не начнётся. Искать способ разбить на 2 потока,
Но я если честно сделал бы по-другому. Есть одна ф-ция, которая слушает любые запросы от любых клиентов, а в качестве параметров принимает идентификатор клиента (чтобы отличать одного от другого) и собственно параметры того, что мы хотим сделать. Например 
Function listen(action, parameters)
If action=="new game"
...