python - 线程写入顺序
问题描述
我正在尝试使用 pygame 制作多客户端游戏。我正在尝试测试客户端向服务器发送数据和服务器发送广播消息的功能,以便所有客户端都可以看到精灵位置。我实现了一个较小的测试样本,其中一些方块移动,这个样本的目的是测试客户端更新从服务器接收到的数据(屏幕上方块的位置)。背后的想法是客户端从初始位置发送更改位置,服务器处理数据并将其发送回单个消息中,如 |1|100|100|2|200|200|3|300|300 等等,以 1当时是第一个位置为 100 和 100 的客户,2 是第二个客户,依此类推。我将留下测试样本:
服务器.py:
import socket,time,threading
playersNo = 0
counter = 0
message = ""
messageList = {}
def on_new_client(clientsocket,addr):
global message, counter, playersNo, messageList
while True:
time.sleep(0.016)
counter +=1
changeX = clientsocket.recv(1024).decode()
splitChange=changeX.split()
#process the data
toSendY, toSendX=processData(splitChange[1], splitChange[0],splitChange[2],splitChange[3])
#Send message
message=str(toSendY)+"|"+str(toSendX)+"|"
if ( counter >= (playersNo+1) ):
counter = 1
messageList[str(counter)]=message
changesBackToClient = str(toSendY)+' ' + str(toSendX)
clientsocket.send(changesBackToClient.encode())
clientsocket.close()
def broadcast_message(messageList):
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
server.settimeout(0.2)
while True:
message=""
for k,v in messageList.items():
message+= k +"|"+v+"|"
message = bytes(message, 'utf-8')
server.sendto(message, ('<broadcast>', 37020))
time.sleep(0.015)
def tcp_socket():
global playersNo,messageList
host = socket.gethostname()
port = 5000
server_socket = socket.socket()
server_socket.bind((host, port))
server_socket.listen(4)
server_socket.settimeout(0.1)
while True:
try:
conn, address = server_socket.accept()
playersNo+=1
t = threading.Thread(target = on_new_client, args =(conn,address,))
t.start()
except socket.timeout:
continue
server_socket.close()
def processData(changeX, changeY,initialValX, initialValY):
dataY = int(initialValY) + int(changeY)
dataX = int(initialValX) + int(changeX)
return dataY, dataX
if __name__ == '__main__':
thrd = threading.Thread(target=broadcast_message,args = (messageList,))
thrd.start()
tcp_socket()
客户端.py:
import pygame,socket,threading,time,random
data=" "
screen_width = 1280
screen_heigth = 960
sqXChange = 0
sqYChange = 0
class Square:
def __init__(self, color,left, top ):
self.color= color
self.left = left
self.top = top
def draw(self):
pygame.draw.rect(screen, self.color,(self.left,self.top,50,50))
sq1 = Square((255,40,0), random.randint(0,1000),random.randint(0,800))
def gameLoop():
global sqXChange, sqYChange, sq1
running = True
while running:
screen.fill((255,255,255))
sq1.draw()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
sqYChange -=5
elif event.key == pygame.K_RIGHT:
sqYChange +=5
elif event.key == pygame.K_UP:
sqXChange -=5
elif event.key == pygame.K_DOWN:
sqXChange +=5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_UP or event.key == pygame.K_DOWN:
sqXChange=0
sqYChange=0
pygame.display.flip()
clock.tick(60)
def tcp_socket():
global sqXChange,sqYChange, sq1,data
host = socket.gethostname()
port = 5000
client_socket = socket.socket()
client_socket.connect((host, port))
while True:
time.sleep(0.016)
changes = str(sqXChange)+' '+str(sqYChange) +' ' + str(sq1.left) +' ' + str(sq1.top)
client_socket.send(changes.encode())
changeFromServer = client_socket.recv(1024).decode().strip().split()
print(data)
sq1.top = int(changeFromServer[0])
sq1.left = int(changeFromServer[1])
client_socket.close()
def broadcast_message():
global data
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) # UDP
client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
client.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
client.bind(("", 37020))
while True:
time.sleep(0.016)
data,addr = client.recvfrom(2048)
data.decode()
if __name__ =="__main__":
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((screen_width,screen_heigth))
t1 = threading.Thread(target = broadcast_message)
t2 = threading.Thread(target = tcp_socket)
t1.setDaemon(True)
t2.setDaemon(True)
t2.start()
t1.start()
gameLoop()
我是 pygame 和线程的新手,所以代码可能有点乱。我现在的问题是数据有时是由 1|100|100|2|200|200 (好的位置)发送的,有时它会根据线程写入 1|200|200|2|100|100 (错误的位置)在那一刻写作。我该如何解决?提前致谢
解决方案
推荐阅读
- c++ - 为什么我需要为不同的图像类型提供不同的转储选项?
- python - 运行从 Python 传递变量的 R 脚本
- python - 如何使用 Jupyter 单元调用 python 命令行程序
- python - 将具有许多二进制数据特征的大量观察结果提供给 TensorFlow
- ios - 快速突出字体的粗体
- node.js - 结果已定义但 result.data 在 .then() 中未定义
- sql - SQL Server:将一行拆分为多行(值)
- css - 在 ReactJS 中逐个淡入节元素
- typescript - 在这个例子的类型声明中这个赋值的意义和目的是什么?
- jquery - 如何在 jquery 中使用 % 而不是 px 来调整大小