when I send message from client 1 , the message does not appear immediately in client 2 ,Although it appears immediately on the server, on client 2 i should double press "enter" to show other messages.
when I send message from client 1 , the message does not appear immediately in client 2 ,Although it appears immediately on the server, on client 2 i should double press "enter" to show other messages.
the server code :
import socket
import select
import sys
from _thread import *
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if len(sys.argv) != 3:
print ("Correct usage: script, IP address, port number")
exit()
IP_address = str(sys.argv[1])
Port = int(sys.argv[2])
server.bind((IP_address, Port))
server.listen(5)
list_of_clients = []
def broadcast(message, connection):
for clients in list_of_clients:
if clients!=connection:
try:
clients.send(message.encode())
except:
clients.close()
remove(clients)
def remove(connection):
if connection in list_of_clients:
list_of_clients.remove(connection)
def clientthread(conn, addr):
# sends a message to the client whose user object is conn
conn.send(b'chat made by galal')
while True:
try:
message = conn.recv(2048).decode()
if message:
print ("<" addr[0] "> " message)
message_to_send = "<" addr[0] "> " message
broadcast(message_to_send, conn)
else:
remove(conn)
except:
continue
while True:
conn, addr = server.accept()
list_of_clients.append(conn)
print (addr[0] " connected")
start_new_thread(clientthread,(conn,addr))
conn.close()
server.close()
the client code :
import socket
import select
import sys
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if len(sys.argv) != 3:
print ("Correct usage: script, IP address, port number")
exit()
IP_address = str(sys.argv[1])
Port = int(sys.argv[2])
server.connect((IP_address, Port))
while True:
# maintains a list of possible input streams
sockets_list = [socket.socket(), server]
read_sockets,write_socket, error_socket = select.select(sockets_list,[],[])
for socks in read_sockets:
if socks != server:
message = sys.stdin.readline()
server.send(message.encode())
sys.stdout.write("<You>")
sys.stdout.write(message)
sys.stdout.flush()
else:
message = socks.recv(2048).decode()
print (message)
server.close()
CodePudding user response:
Your client code waits until pressed enter
since there is a
sys.stdin.readline()
in your client code (Line 17).
sys.stdin.readline()
waits for the press of your enter
key, since it tries to read a newline from your stdin
(Your input), therefore blocking the whole execution of your client application.
What you have to do is using separate threads for:
- Recieving messages print them
- Read from
stdin
(e.g. throughsys.stdin.readline()
orinput()
) and send that message to the server like you're already doing
CodePudding user response:
I think the issue is the client's for loop.
sys.stdin.readline()
stops the flow until Enter is pressed, so when you send a message from client1
, client2
is still waiting for the user to write its own message. Basically since the first item in read_sockets
is always socket.socket()
every client's first action will be to wait for user input to send a message. The server on the other hand is always listening and never waits, so it receives it immediately.
To solve this you can either have an async connection, meaning you send 1 message then wait to receive 1 message and so on, or use multithreading and dedicate a thread to receiving and one to sending.