fahim shahoriar
fahim shahoriar

Reputation: 11

pygame stop responding while socket receiving data

I am trying to make an online tictactoc game with pygame and socket. everything is working well. but there is a small problem that is when the server or client in on receiving mode and waiting to receive data if that takes more than 4 or more sec. then pygame's GUI stops responding. but if data sent then it starts working normally. it happens while receiving data and it took more than 4 or more seconds. please me to solve out

server.py codes

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 codes

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

Upvotes: 1

Views: 174

Answers (1)

Jeffrey
Jeffrey

Reputation: 11400

If you look up the documentation:

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

socket.recv(bufsize[, flags]) Receive data from the socket. The return value is a bytes object representing the data received. The maximum amount of data to be received at once is specified by bufsize. See the Unix manual page recv(2) for the meaning of the optional argument flags; it defaults to zero.

It points you to flags you can use, in the underlying OS implementation. I don't know the portable way to do this, but the functionality you want is to pass MSG_DONTWAIT. That way, if a message has not arrived yet, you get to learn about it. That means your program can continue to animate and try again later. You'll need to return None in the meantime, and adjust your code to detect that and retry again until the message has arrived.

There is also: socket.SOCK_NONBLOCK in Python. this might be the flag to pass:

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

but don't forget to check the returned value before trying to decode it.

Upvotes: 2

Related Questions