Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python TCP套接字对于我在真实网络上的多人游戏来说太慢了_Python_Sockets_Networking_Tcp_Multiplayer - Fatal编程技术网

Python TCP套接字对于我在真实网络上的多人游戏来说太慢了

Python TCP套接字对于我在真实网络上的多人游戏来说太慢了,python,sockets,networking,tcp,multiplayer,Python,Sockets,Networking,Tcp,Multiplayer,我已经在skribble.io上编写了一个绘图和猜谜游戏simular,我正在使用TCP Socketserver向所有连接的玩家提供游戏信息。在客户端是一个运行while-true循环的线程,该循环持续请求所需的信息;在服务器端是一个运行while-true循环的线程,该循环接收请求并给出正确的响应。对于数据的序列化,我使用pickle。当我在本地机器上用运行的服务器和一些客户端测试我的游戏时,一切正常,但如果我在本地网络或互联网上测试它,它在客户端开始变得非常滞后,所有事情都需要花费大量的时

我已经在skribble.io上编写了一个绘图和猜谜游戏simular,我正在使用TCP Socketserver向所有连接的玩家提供游戏信息。在客户端是一个运行while-true循环的线程,该循环持续请求所需的信息;在服务器端是一个运行while-true循环的线程,该循环接收请求并给出正确的响应。对于数据的序列化,我使用pickle。当我在本地机器上用运行的服务器和一些客户端测试我的游戏时,一切正常,但如果我在本地网络或互联网上测试它,它在客户端开始变得非常滞后,所有事情都需要花费大量的时间来显示正确的服务器信息,例如正在运行的计时器我的游戏不是每秒钟更新一次,而且画面也很落后

客户端:

def receive_data():
    global connected_clients, client, start, grid, in_game, lobby_id
    while True:
        try:
            if not in_game:
                data = network.receive()
                if isinstance(data, list):  # get connected clients
                    connected_clients = data
                    for c in connected_clients:  # get current client
                        if c.uid == client.uid:
                            client = c
                elif data == 'start':
                    start = True
                    in_game = True

            else:
                if not client.drawing:
                    res = network.get('grid')['grid']  # get grid
                    grid.update(res)

                # get round information
                topbar.word = network.get('word')['word']  # get word
                client.drawing = network.get('drawing')['drawing']
                topbar.time = network.get('time')['time']  # get round time
                topbar.round = network.get('round')['round']

                response = network.get('clients')  # get all connected clients
                connected_clients = response['clients']
                for c in connected_clients:  # get current client
                    if c.uid == client.uid:
                        client = c

                messages = network.get('chat')['chat']  # get chat
                chat.update(messages, client)
        except:
            pass
网络方法get():

我已经想到了一个可能的解决方案,即从TCP切换到UDP和TCP,但我不知道如何以一种可以发送所有必要信息的方式实现这两种方式


PS:对于任何英语错误,我深表歉意,感谢您的帮助。

您尝试过TCP\u NODELAY吗?你有没有考虑过,每次你打电话给
network.get
都需要时间?在互联网上,这可能需要0.3秒。这意味着如果你调用它7次,可能需要2.1秒。@Malt是的,我已经尝试过了。@user253751是的,我知道发送数据和返回正确的数据需要很长时间,但这实际上是我的问题。那么,您知道如何提高时间效率吗?设计它使客户机不必等待服务器?
def get(self, data):  # returns the response for the request
        try:
            self.client.send(pickle.dumps(data))
            buff_size = 4096
            data = bytearray()
            while True:
                chunk = self.client.recv(buff_size)
                data += chunk
                if len(chunk) < buff_size:
                    break
            return pickle.loads(data)
        except Exception as e:
            print(e)
def handle_player(self, connection, player):
        data = None
        send_msg = {}
        while True:
            try:
                try:
                    data = self.receive(connection)
                except:
                    pass
                if not self.in_game:  # lobby logic

                    if data == 'ready':
                        player.ready = True
                        self.broadcast(self.players_to_clients())

                    if self.all_players_ready():
                        self.broadcast('start')
                        self.game = Game(self.players)
                        for p in self.players:
                            p.set_game(self.game)
                        self.in_game = True

                elif self.in_game:  # in game logic
                    if player.game:

                        if isinstance(data, list):
                            player.game.grid.completely_update(data)
                        elif isinstance(data, dict):
                            player.game.make_player_guess(player, data['guess'])

                        if data == 'word':
                            send_msg['word'] = player.game.round.word
                        elif data == 'drawing':
                            player.drawing = player.game.round.player_drawing == player
                            if player.drawing:
                                send_msg['drawing'] = True
                            else:
                                send_msg['drawing'] = False
                        elif data == 'clients':
                            send_msg['clients'] = self.players_to_clients()
                        elif data == 'time':
                            send_msg['time'] = player.game.round.draw_time
                        elif data == 'grid':
                            send_msg['grid'] = player.game.grid.get_grid()
                        elif data == 'chat':
                            send_msg['chat'] = player.game.chat.messages
                        elif data == 'round':
                            send_msg['round'] = player.game.round_count

                        connection.send(pickle.dumps(send_msg))

                    else:
                        pass

            except socket.error:
                print(f'{player.name} disconnected.')
                player.game.player_disconnect(player)
                if player in self.players:
                    self.players.remove(player)
                if connection in self.connections:
                    self.connections.remove(connection)
                self.broadcast(self.players_to_clients())
                break