BlockingIOError: [Errno 35] Resource temporarily unavailable [sockets][multi-threading]

Viewed 323

I have a server with multiple clients. The server has a separate thread for each client. This is my threaded client function in server.py Earlier, I open the server and run s.accept() to accept clients, but since I don't want this to block my programme, I set s.setblocking(0)

def threaded_client(conn, addr, clientID):
    clientUsernameLength = int(conn.recv(HEADER).decode(FORMAT))
    clientUsername = pickle.loads(conn.recv(clientUsernameLength))

    print(f"{clientUsername} joined!")

    #add this player to the players dictionary
    **clientDataLength = int(conn.recv(HEADER).decode(FORMAT))**
    clientDataDict = pickle.loads(conn.recv(clientDataLength))
    players[clientUsername] = clientDataDict

    send(conn, f"Thanks for joining us, {clientUsername}!")

    connected = True
    while connected: #continually run while the client is still connected
        try: #check if server has received a message from a player
            clientMessageLength = conn.recv(HEADER).decode(FORMAT)

            if clientMessageLength:
                clientMessageLength = int(clientMessageLength)
                clientMessage = pickle.loads(conn.recv(clientMessageLength))
                print(f"[Client {clientID}][{clientMessage}]")

                if clientMessage == DISCONNECT_MESSAGE:
                    print(f"Client {clientID} disconnected")
                    send(conn, "Thanks for joining us!")
                    connected = False
                else:
                    send(conn, "Message received!")
        except socket.error: #no message received
            pass
    conn.close()

My send() function simply uses a buffer with HEADER = 64, and FORMAT = "utf-8"

def send(conn, message):
    reply = pickle.dumps(message)
    replyLength = len(reply)
    sendHeader = bytes(str(replyLength), FORMAT)
    sendHeader += b" " * (HEADER - len(sendHeader))
    conn.send(sendHeader) #first send the length of the mesage
    #now send the message
    conn.send(reply)

On the client side, I first send in the username and then a dictionary.

dataDict = {"score": score, "health": 10, "items": ["shield", "mirror"]}
while True:
    try:
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client.connect(ADDR)
        send(username)
        send(dataDict)
        break
    except ConnectionRefusedError:
        print("Waiting for server...")

However, clientDataLength = int(conn.recv(HEADER).decode(FORMAT)) encounters an error:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "<server file>, line 127, in threaded_client
    clientDataLength = conn.recv(HEADER).decode(FORMAT)
BlockingIOError: [Errno 35] Resource temporarily unavailable

Why is this?

0 Answers
Related