线程写入顺序

问题描述

我正在尝试使用 pygame 制作多客户端游戏。我正在尝试测试客户端向服务器发送数据和服务器发送广播消息的功能,以便所有客户端都可以看到精灵位置。我实现了一个较小的测试样本,其中一些方块移动,这个样本的目的是测试客户端更新从服务器接收的数据(屏幕上方块的位置)。背后的想法是客户端从初始位置发送更改位置,服务器处理数据并将其发送回单个消息,如 |1|100|100|2|200|200|3|300|300 等等是当时位置 100 和 100 的第一个客户,2 是第二个客户,依此类推。 我将离开测试样本:

server.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()

client.py:

import pygame,socket,threading,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),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,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.IPPROTO_UDP) # UDP
    client.setsockopt(socket.soL_SOCKET,1)
    client.setsockopt(socket.soL_SOCKET,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(错误位置)在那一刻写作。我该如何解决?提前致谢

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)