Я кодирую небольшой сервер чата с сокетом для личного использования, и наткнулся и выпускаю
Мой клиент - простая программа с двумя потоками, одна ожидает ввода пользователя, другая - на сервере; этот код работает отлично:
import socket
import threading
from threading import Thread
username = input("Username? >")
host = input("host ip?")
port = 8000
Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Socket.connect((host,port))
Socket.send(username.encode())
print(Socket.recv(1024).decode())
def SendMessage():
while True:
Socket.send(input("").encode())
def RecvMessage():
while True:
print(Socket.recv(1024).decode())
msgthread = Thread(target = SendMessage, args = ())
recvthread = Thread(target = RecvMessage, args = ())
msgthread.start()
recvthread.start()
(простите за неаккуратный код, он был создан за 20 минут в понедельник вечером)
Как видите, я вызываю два потока, в каждом из которых есть функции остановки, и это работает без проблем.
Однако на сервере возникают проблемы:
import socket
import threading
from threading import Thread
connections = []
host = ""
port = 8000
threads = []
def ListenForCommands():
while True:
print(input())
def SearchForConnections():
global connections, threads
while True:
conn, addr = Socket.accept()
username = conn.recv(10).decode()
conn.send(("You have successfully connected to the server!").encode())
print(username + " (" + str(addr[0]) + ":" + str(addr[1]) + ") Joined")
for i in range(len(connections)):
if connections[i][0] != conn:
connections[i][0].send((username + " Joined").encode())
connections += [[conn,addr,username]]
threads += [Thread(target = Listen, args = (conn, ))]
threads[-1].start()
def Listen(conn):
global connections, threads
while True:
for i in range(len(connections)):
if connections[i][0] == conn:
username = connections[i][2]
try:
data = conn.recv(1024).decode()
print(username + ": " + data)
for i in range(len(connections)):
if connections[i][0] != conn:
connections[i][0].send((username + ": " + data).encode())
except:
print(username + " Disconnected")
for i in range(len(connections)):
if connections[i][0] == conn:
connections.remove(connections[i])
break
for i in range(len(connections)):
connections[i][0].send((username + " Disconnected").encode())
return;
Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Server created")
Socket.bind((host,port))
Socket.listen(3)
ListenThread = Thread(target = ListenForCommands, args = ())
ListenThread.start()
SearchForConnections()
Источник проблемы в следующих функциях:
def ListenForCommands():
while True:
print(input())
def SearchForConnections():
global connections, threads
while True:
conn, addr = Socket.accept()
username = conn.recv(10).decode()
conn.send(("You have successfully connected to the server!").encode())
print(username + " (" + str(addr[0]) + ":" + str(addr[1]) + ") Joined")
for i in range(len(connections)):
if connections[i][0] != conn:
connections[i][0].send((username + " Joined").encode())
connections += [[conn,addr,username]]
threads += [Thread(target = Listen, args = (conn, ))]
threads[-1].start()
Программа, кажется, останавливается при достижении этой строки
print(username + " (" + str(addr[0]) + ":" + str(addr[1]) + ") Joined")
и отлично работает без него; однако в клиентской программе это, похоже, не так.
функция ListenForCommands (на данный момент просто распечатывает пользовательский ввод) объявляется как поток:
ListenThread = Thread(target = ListenForCommands, args = ())
ListenThread.start()
и функция SearchForConnections вызывается нормально. Тем не менее, кажется, что вся программа останавливается до тех пор, пока от пользователя не будет получен ввод, в отличие от клиентской стороны, которая, кажется, работает отлично.
Я думаю, что упускаю что-то совершенно очевидное, но потерял несколько часов назад, и ему бы очень хотелось, если бы кто-то мог помочь мне увидеть ошибку в моих путях!