Reputation: 11
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
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