How To Use A Socket Without Waiting In Python
I create a game in Python, the game consists of several snakes each controlled by a different computer. Each computer sends to the server computer the angle to which the snake is d
Solution 1:
You can use sockets in non-blocking mode:
import pygame as pg
import socket
pg.init()
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("localhost", 55555)) # Connect to server
client.setblocking(False) # Prevent socket from waiting for input
W, H = 640, 480
FLAGS = 0
screen = pg.display.set_mode((W, H), FLAGS)
W, H = screen.get_size()
font = pg.font.SysFont("arial", 30)
text = ""
running = True
while running:
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
elif event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE:
running = False
try:
raw = client.recv(1024)
except BlockingIOError:
pass # No new data. Reuse old data
else:
text = raw.decode("utf-8") # New data has arrived. Use it
screen.fill((0, 0, 0))
img = font.render(text, True, (255, 255, 255))
r = img.get_rect(center=(W // 2, H // 2))
screen.blit(img, r)
pg.display.update()
This assumes a simple server script like this:
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("localhost", 55555))
server.listen()
while True:
client, address = server.accept()
print("Connected to", address)
while True:
line = input("> ")
try:
client.send(line.encode("utf-8"))
except ConnectionError as e:
print(e)
print("Disconnecting")
client.close()
break
It will display whatever line of text you entered on the server in the center of the pygame window.
If you want t he reverse situation, where the server has a pygame window open, you can use these pieces of code:
server:
import socket
import pygame as pg
pg.init()
W, H = 640, 480
FLAGS = 0
screen = pg.display.set_mode((W, H), FLAGS)
W, H = screen.get_size()
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("localhost", 55556))
server.listen(1)
server.setblocking(False)
client = None
font = pg.font.SysFont("arial", 30)
text = ""
clock = pg.time.Clock()
running = True
while running:
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
elif event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE:
running = False
elif event.type == pg.VIDEORESIZE:
screen = pg.display.set_mode(event.size, FLAGS)
W, H = screen.get_size()
# Logic
dt = clock.tick()
if client is None:
try:
client, address = server.accept()
except BlockingIOError:
pass
else:
try:
raw = client.recv(1024)
except BlockingIOError:
pass
else:
text = raw.decode("utf-8")
# Render
screen.fill((0, 0, 0))
img = font.render(text, True, (255, 255, 255))
r = img.get_rect(center=(W // 2, H // 2))
screen.blit(img, r)
pg.display.update()
pg.display.set_caption(f"FPS: {clock.get_fps():.2f}")
client
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("localhost", 55556))
try:
while True:
line = input("> ")
try:
client.send(line.encode("utf-8"))
except ConnectionError as e:
print(e)
print("Disconnecting")
break
finally:
client.close()
If you want both to have pygames windows, I would suggest considering using multiple clients and one non-pygame server instead. But similar code should work anyway.
Post a Comment for "How To Use A Socket Without Waiting In Python"