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