Skip to content Skip to sidebar Skip to footer

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"