Python server gets stuck when accepting a second connection

Viewed 26

I have a server script and a client scripts for a game, I'm trying to get the server to accept two or more connections. When the first client connects, everything works smoothly, however when I connect a second client the server gets stuck at data = conn.recv(2048).decode("utf-8"). I've tried running the server on both my network and Linode so I'm fairly sure that it's not a firewall issue.

Client script:

import pygame
from pygame.locals import *
vec = pygame.math.Vector2

WHITE = (255,255,255)
RED = (255,0,0)
BLUE = (0,0,255)

pygame.init()

win = pygame.display.set_mode((500,500))

class Player(pygame.sprite.Sprite):
    def __init__(self, pos):
        super().__init__()
        #self.username = input("Please enter your username: ")
        self.surf = pygame.Surface((50, 50))
        self.surf.fill(BLUE)
        self.rect = self.surf.get_rect()
        self.grounded = False


        self.pos = vec(int(pos[0]), int(pos[1]))
        self.vel = vec(0,0)
        self.acc = vec(0,0)

        self.ACC = 0.5
        self.FRIC = -0.12

    def move(self):
        self.acc = vec(0,0.75)

        pressed_keys = pygame.key.get_pressed()

        if pressed_keys[K_LEFT]:
            self.acc.x = -self.ACC
        if pressed_keys[K_RIGHT]:
            self.acc.x = self.ACC
        if pressed_keys[K_UP] and self.grounded:
            self.vel.y = -15
            self.grounded = False


        self.acc.x += self.vel.x * self.FRIC
        self.vel += self.acc

        self.pos += self.vel + 0.5 * self.acc

        self.rect.midbottom = self.pos

    def update(self):
        hits = pygame.sprite.spritecollide(player , platforms, False)
        if hits:
            self.pos.y = hits[0].rect.top + 1
            self.vel.y = 0
            self.grounded = True

class Platform(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.surf = pygame.Surface((500, 20))
        self.surf.fill(RED)
        self.rect = self.surf.get_rect(center=(500/2, 490))

network = Network()
startPos = network.pos
startPos = startPos.strip("()")
startPos = startPos.split(",")


player = Player(startPos)

plat_bot = Platform()
platforms = pygame.sprite.Group()
platforms.add(plat_bot)

clock = pygame.time.Clock()
running = True

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    keys_pressed = pygame.key.get_pressed()


    player.move()
    player.update()

    win.fill(WHITE)

    otherPlayers = network.send(str(player.pos))
    print (otherPlayers)


    win.blit(player.surf, player.rect)
    win.blit(plat_bot.surf, plat_bot.rect)

    pygame.display.update()
    clock.tick(60)

pygame.quit()

Network script (only called in client script):


class Network:
    def __init__(self):
        self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server = "176.58.112.169"
        self.port = 5555
        self.addr = (self.server, self.port)
        self.pos = self.connect()

    def connect(self):
        try:
            self.client.connect(self.addr) #Connect to the server

            position = self.client.recv(2048).decode() #Get position from server
            print ("connected")
            return position #pass through
        except Exception as e:
            print (f"Error: {e}")

    def send(self, data):
        try:
            self.client.send(str.encode(data))
            return self.client.recv(2048).decode()
        except socket.error as e:
            print (e)

Server script:

import socket
from _thread import *

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server = ""  
port = 5555  

try:
    s.bind((server, port))

except socket.error as e:
    print(e)

s.listen(2)

print("Awaiting connection...")

players = []


def threaded_client(thisCon):
    global players

    playerNum = len(players) + 1  # Length of the list +1 is the current player number
    reply = str((playerNum * 100, 100))  # Use the number of the player to find starting position
    players.append(reply)  # Using the player's position add them to the list

    thisCon.sendall(reply.encode())  # send the client their position
    print (f"Player number: {playerNum}")

    while True:
        try:
            data = conn.recv(2048).decode("utf-8")

            if playerNum == 2:
                print(reply)
            print (f"User sent: {reply}")

            if not data:
                print("Disconnected")

                break
            else:
                pass

            thisCon.sendall(str(players).encode()) #currently sending whole list of players position, not in the final design

        except Exception as e:
            print(e)


while True:
    # Continually look for connections
    conn, addr = s.accept()
    print(f"Connected to {addr}")

    start_new_thread(threaded_client, (conn,))

P.S: sorry for the long code/bad way of doing it, I'm still learning everything

0 Answers
Related