0

All this program should do is accept inputs from 2 clients simultaneously and print them out, but instead it accepts 1 input from the first client to connect, then starts accepting inputs infinitely from the second client, but not from the first anymore. Any tips on how to fix this code? (shown below)

import socket
import select
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("127.0.0.1", 4000))
s.listen(5)
sockets = []
sockets.append(s)
while True:
    (read, write, err) = select.select(sockets, [], [])
    for socket in read:
        if (socket == s):
            (c, a) = socket.accept()
            sockets.append(c)
            print ("Received connection from: ", a)
    message = c.recv(80).decode()
    print (message + " from " + str(a[1]))
Elmo1768
  • 1
  • 1

1 Answers1

1

You need to receive data from client only when the data is available to prevent blocking.

message = c.recv(80).decode()

The above line read regarlessly; and it will read only from the last client that accepted.

Here's a modified version of the for loop:

for peer in read:
    if peer == s:
        (c, a) = peer.accept()
        sockets.append(c)
        print("Received connection from:", a)
    else:
        # Receive data from client only if data is available
        message = peer.recv(80).decode()
        if message:
            print(message, "from", peer.getpeername())
        else:
            # No message to read => clinet disconnection
            print(peer.getpeername(), "disconnected")
            sockets.remove(peer)

I renamed socket to peer to prevent name shadowing; Using socket as a variable name will shadow socket module reference.

falsetru
  • 357,413
  • 63
  • 732
  • 636