Привет, я пытаюсь создать очень простую программу для однорангового чата на python. Первый пользователь может запустить приведенную ниже программу server.py для привязки к сокету.
import sys
import socket
import select
import threading
# Bind to socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('127.0.0.1', 11111))
s.listen()
def chat(conn, addr):
# Set blocking to false so that program can send and receive messages at the same time
conn.setblocking(0)
# Receive messages using select
while conn in select.select([conn], [], [], 0)[0]:
text = conn.recv(4096)
if text:
print("{}: {}".format(addr, text))
else:
return
# get user input and send message
while True:
msg = input(">>>")
conn.send(msg.encode())
if __name__ == '__main__':
## Accept connections and start new thread
(conn, addr) = s.accept()
threading.Thread(target=chat, args=([conn, addr])).start()
Затем другой пользователь может использовать netcat для подключения к серверу и связи. Однако программа может только получить ввод пользователя и отправить его другой стороне. Пользователь с другой стороны не может отправлять сообщения.
Привет, извините, я не упомянул четко, я хочу, чтобы клиент и сервер могли отправлять сообщения, не дожидаясь ответа. Если используется блокирующий сокет, я не могу отправлять сообщения и получать их одновременно.






input() блоки, так что вы проваливаетесь через свою chat функцию и входите в цикл input() и больше никогда не проверяете получение. Получите в потоке и введите входной цикл в основной поток. TCP является полнодуплексным, поэтому вы можете одновременно отправлять и получать данные в двух потоках, не отключая блокировку.
Мне также нужно было добавить новую строку в send(), так как мой netcat буферизовал строки.
import socket
import threading
# Bind to socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 11111))
s.listen()
def chat(conn, addr):
while True:
text = conn.recv(4096)
if not text: break
print("{}: {}".format(addr, text))
if __name__ == '__main__':
## Accept connections and start new thread
conn, addr = s.accept()
threading.Thread(target=chat, args=(conn, addr), daemon=True).start()
# get user input and send message
while True:
msg = input(">>>")
conn.sendall(msg.encode() + b'\n')
Если вы создаете поток для каждого клиента, вам не нужно использовать неблокирующий режим.