1

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

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

I am still confused. but I have tried the flag after watching your answer but it says "AttributeError: module 'socket' has no attribute 'SOCK_NONBLOCK' " will you please provide me some example

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.