簡體   English   中英

pygame 在套接字接收數據時停止響應

[英]pygame stop responding while socket receiving data

我正在嘗試使用 pygame 和套接字制作在線 tictactoc 游戲。 一切正常。 但是有一個小問題是當服務器或客戶端處於接收模式並等待接收數據時,如果這需要超過 4 秒或更長時間。 然后 pygame 的 GUI 停止響應。 但如果發送數據,則它開始正常工作。 它在接收數據時發生,並且花費了超過 4 秒或更長時間。 請我解決

server.py 代碼

import socket
import pygame
import sys


IP = socket.gethostbyname(socket.gethostname())
PORT = 5555
Biended_adrs = (IP, PORT)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(Biended_adrs)
server.listen()
conn, addr = server.accept()
print(f"{addr} connected!")

def Send(row, col):
    data = str((row, col))
    conn.send(data.encode())

def Receive():
    data = conn.recv(1024)
    return data.decode()




pygame.init()
display = pygame.display.set_mode((600, 600))
pygame.display.set_caption("Server")

GRAY = (100, 111, 111)
LineWidth = 10

def DrawLine():
    pygame.draw.line(display, GRAY, (0, 200), (600, 200), LineWidth) # h1
    pygame.draw.line(display, GRAY, (0, 400), (600, 400), LineWidth) # h2
    pygame.draw.line(display, GRAY, (200, 0), (200, 600), LineWidth) # v1
    pygame.draw.line(display, GRAY, (400, 0), (400, 600), LineWidth) # v2

DrawLine()


firstPlayer = conn.recv(1024)
player = firstPlayer.decode()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

        if event.type == pygame.MOUSEBUTTONDOWN:
            mouseX = event.pos[0]
            mouseY = event.pos[1]


            clickedRow = int(mouseY // 200)
            clickedCol = int(mouseX // 200)


            if player == "1":
                try:
                    Send(clickedRow, clickedCol)
                    player = "2"
                    conn.send(player.encode())
                except Exception:
                    pass

            else:
                pass
        if player == "2":
            try:
                Clientdata = Receive()
                print(Clientdata, "Client Send!")
                player = conn.recv(1024).decode()
                print(player)
                receive = False
            except Exception:
                pass

        else:
            pass


        pygame.display.update()

client.py 代碼

import socket
import pygame
import sys

pygame.init()
display = pygame.display.set_mode((600, 600))
pygame.display.set_caption("Client")


HOST = socket.gethostbyname(socket.gethostname())
PORT = 5555

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((HOST, PORT))

draw = DrawLine()

def Send(row, col):
    data = str((row, col))
    client.send(data.encode())

def Receive():
    data = client.recv(1024)
    return data.decode()

GRAY = (100, 111, 111)
LineWidth = 10

def DrawLine():
    pygame.draw.line(display, GRAY, (0, 200), (600, 200), LineWidth) # h1
    pygame.draw.line(display, GRAY, (0, 400), (600, 400), LineWidth) # h2
    pygame.draw.line(display, GRAY, (200, 0), (200, 600), LineWidth) # v1
    pygame.draw.line(display, GRAY, (400, 0), (400, 600), LineWidth) # v2


firstPlayer = "1"
client.send(firstPlayer.encode())
player = "1"

while True:
    for event in pygame.event.get():
        If event.type == pygame.QUIT:
            sys.exit()

        if event.type == pygame.MOUSEBUTTONDOWN:
            mouseX = event.pos[0]
            mouseY = event.pos[1]
            clickedRow = int(mouseY // 200)
            clickedCol = int(mouseX // 200)

            if player == "2":
                try:
                    Send(clickedRow, clickedCol)
                    player = "1"
                    client.send(player.encode())
                except Exception:
                    pass


        if player == "1":
            try:
                data = Receive()
                print(data, "Server Send!")
                player = client.recv(1024).decode()
                print(player)
            except Exception:
                pass
        else:
            pass


        pygame.display.update()

如果您查看文檔:

https://docs.python.org/3/library/socket.html

socket.recv(bufsize[, flags]) 從套接字接收數據。 返回值是一個字節 object 代表接收到的數據。 一次接收的最大數據量由 bufsize 指定。 有關可選參數標志的含義,請參見 Unix 手冊頁 recv(2); 它默認為零。

它指向您可以在底層操作系統實現中使用的標志。 我不知道執行此操作的可移植方式,但您想要的功能是傳遞MSG_DONTWAIT 這樣,如果消息尚未到達,您就可以了解它。 這意味着您的程序可以繼續制作動畫並稍后重試。 與此同時,您需要返回None ,並調整您的代碼以檢測到這一點並重試,直到消息到達。

還有: socket.SOCK_NONBLOCK中的socket.SOCK_NONBLOCK。 這可能是要傳遞的標志:

conn.recv(1024, flags = socket.SOCK_NONBLOCK)

但不要忘記在嘗試解碼之前檢查返回的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM