【发布时间】:2021-02-11 01:15:54
【问题描述】:
我在开发多人游戏时遇到了数据会被发送两次的错误。我和一个玩家一起工作得很好,但是一旦另一个玩家加入服务器,数据就会被发送两次。如果只连接了一个客户端,则从服务器接收到的数据是这样的:{"player locations": [[1, 84, 100, false, ["n", "a", "m", "e"]]]}。这是连接两个客户端时从服务器接收到的数据:
{"player locations": [[1, 80, 102, true, ["P", "l", "a", "y", "e", "r", "O", "n", "e"]], [2, 57, 102, false, ["P", "l", "a", "y", "e", "r", "T", "w", "o"]]]}{"player locations": [[1, 80, 102, true, ["P", "l", "a", "y", "e", "r", "O", "n", "e"]], [2, 57, 102, false, ["P", "l", "a", "y", "e", "r", "T", "w", "o"]]]}
这是服务器发送的数据
b'{"player locations": [[1, 80, 102, true, ["P", "l", "a", "y", "e", "r", "O", "n", "e"]], [2, 57, 102, false, ["P", "l", "a", "y", "e", "r", "T", "w", "o"]]]}'
这是 server.py 文件的代码:
IMPORTS/SETUP -------------------------------------------------------------------------------------------------------- #
import socket, sys, json
import threading
# FUNCTIONS ------------------------------------------------------------------------------------------------------------ #
def get_ip_port(path):
with open(path, "r") as ipf:
ipf_data = ipf.read()
ipf.close()
data_split = ipf_data.split(":")
return [data_split[0],int(data_split[1])]
print(get_ip_port("serverip.txt"))
def update_clients(updatemessage):
"""
update_data[0][0] is the player's x pos
update_data[0][1] is the player's y pos
update_data[1] is the player's flip bool
update_data[2] is the player's name str
:param updatemessage:
:return:
"""
# player key structure: {playerid:[[x,y],flip,name]}
update_data = json.loads(updatemessage)
playerid = [key for key in update_data.keys()][0]
update_lst = update_data[playerid]
playerid = update_lst[0]
#print(update_lst)
#print(playerid)
print(players)
if playerid == 0:
return
playermap[playerid][0][0] = update_lst[1]
playermap[playerid][0][1] = update_lst[2]
playermap[playerid][1] = update_lst[3]
playermap[playerid][2] = update_lst[4]
remove = []
for player_socket in players:
update = {'player locations':[]}
for key, value in playermap.items():
update['player locations'].append([key, value[0][0], value[0][1], value[1], value[2]])
try:
print(json.dumps(update).encode())
player_socket.sendall(json.dumps(update).encode())
except Exception as e:
remove.append(player_socket)
print(e)
continue
for r in remove:
players.remove(r)
def client_thread(conn, player_id):
while True:
try:
recvdata = conn.recv(bufsize)
if recvdata:
update_clients(recvdata)
else:
break
except Exception as e:
print(e)
break
playermap.pop(player_id)
players.remove(conn)
conn.close()
# VARIABLES ------------------------------------------------------------------------------------------------------------ #
MAX_PLAYER_COUNT = 15
ipport = get_ip_port("serverip.txt")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(tuple(ipport))
s.listen(MAX_PLAYER_COUNT+1)
bufsize = 2048
global playermap
global players
players = []
playermap = {}
playerstartpos = [50,50]
print("Server has started, waiting for connections.")
#player key structure: {playerid:[[x,y],flip,name]}
# SERVER LOOP ---------------------------------------------------------------------------------------------------------- #
while True:
conn, addr = s.accept()
print(f"Connection from {addr}")
players.append(conn)
playerid = len(players)
playermap[playerid] = [[playerstartpos[0], playerstartpos[1]],False,""]
conn.send(json.dumps({"id update": playerid}).encode())
pthread = threading.Thread(target=client_thread, args=[conn,playerid])
pthread.start()
这是从服务器接收数据的client.py文件中的代码:
# player key structure: {playerid:[[x,y],flip,name]}
# update = {'player locations':[[value.id, value.x, value.y, value.flip, value.name]]}
ins, outs, ex = select.select([n.socket], [], [], 0)
for in_ in ins:
data = in_.recv(2048)
print(data.decode() + "\n")
if data:
try:
socket_event = json.loads(data)
except Exception as e:
print(e)
event_type = [key for key in socket_event.keys()][0]
event_data_lst = socket_event[event_type]
if event_type == 'id update':
player.id = event_data_lst
if event_type == 'player locations':
#socket_event.pop(0)
players = []
for splayer in event_data_lst:
if splayer[0] != player.id:
socket_player = Player((splayer[1], splayer[2]), (15,37), splayer[4], splayer[0])
socket_player.flip = splayer[3]
players.append(socket_player)
#else:
# player.x = splayer[1]
# player.y = splayer[2]
【问题讨论】:
标签: python sockets networking pygame