Я думаю, что ваша проблема в том, что в вашем цикле событий есть два места, где вы блокируете:
message = sys.stdin.readline().encode()
Здесь вы блокируете, пока пользователь не нажал return - в течение этого времени ваша программа не можетотвечать на любые данные, полученные по сети, потому что он заблокирован в ожидании данных от стандартного ввода.
... и:
return_msg = sock.recv( 1024 )
Здесь вы ожидаете получения данныхиз сети - в течение этого времени ваша программа не может отвечать на любые данные, полученные от stdin, потому что она заблокирована в ожидании данных из сети.
Поведение, которое вы в идеале хотели бы иметь, дляВаша программа ожидает как стандартный, так и сетевой трафик одновременно - т.е. блокирует его до тех пор, пока пользователь не нажмет return, или некоторые сетевые данные будут получены, в зависимости от того, что произойдет раньше.
Самый простой способ добиться такого поведения - использовать select()
;его цель - блокировать, пока не будет готов по крайней мере один из нескольких файловых дескрипторов.(Тем не менее, обратите внимание, что Windows не поддерживает использование select()
в stdin, поэтому, если ваша программа должна работать под Windows, вам, вероятно, придется вместо этого создавать второй поток).
Чтобы реализовать цикл обработки событий, используяselect()
, добавьте import select
в начало вашего скрипта, затем замените цикл событий на что-то вроде этого:
while True:
## block here until either sock or sys.stdin has data ready for us
readable, writable, exceptional = select.select([sock, sys.stdin], [], [])
if sys.stdin in readable:
## read a message from standard input
message = sys.stdin.readline().encode()
if len(message) != 0:
sock.send(message)
if sock in readable:
## read a message from the network
try:
return_msg = sock.recv( 1024 )
if (return_msg):
print("Message received: " + return_msg.decode())
else:
print("Other side shut down")
break
except:
print("recv() threw an exception")
break