【问题标题】:pygame stop responding while socket receiving datapygame 在套接字接收数据时停止响应
【发布时间】:2021-07-17 03:01:56
【问题描述】:

我正在尝试使用 pygame 和 socket 制作一个在线 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()

【问题讨论】:

    标签: python sockets pygame


    【解决方案1】:

    如果您查看文档:

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

    socket.recv(bufsize[, flags]) 从套接字接收数据。回报 value 是一个字节对象,表示接收到的数据。最大值 一次接收的数据量由 bufsize 指定。见 Unix 手册页 recv(2) 中可选参数的含义 旗帜;默认为零。

    它指向您可以在底层操作系统实现中使用的标志。我不知道这样做的便携方式,但你想要的功能是通过MSG_DONTWAIT。这样,如果消息尚未到达,您就可以了解它。这意味着您的程序可以继续制作动画并稍后重试。同时,您需要返回None,并调整您的代码以检测到这一点,然后重试,直到消息到达。

    还有:socket.SOCK_NONBLOCK 在 Python 中。这可能是要传递的标志:

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

    但不要忘记在尝试解码之前检查返回的值。

    【讨论】:

    • 我还是一头雾水。但我在看了你的回答后尝试了这个标志,但它说“AttributeError:模块'socket'没有属性'SOCK_NONBLOCK'”请你给我一些例子
    猜你喜欢
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 2023-02-22
    • 2020-11-11
    • 2017-01-17
    • 1970-01-01
    • 2014-10-12
    • 1970-01-01
    相关资源
    最近更新 更多