Многопоточность Python: многопоточный ввод () приостанавливает другие потоки в одной программе, но не в другой? - PullRequest
0 голосов
/ 13 ноября 2018

Я кодирую небольшой сервер чата с сокетом для личного использования, и наткнулся и выпускаю Мой клиент - простая программа с двумя потоками, одна ожидает ввода пользователя, другая - на сервере; этот код работает отлично:

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 вызывается нормально. Тем не менее, кажется, что вся программа останавливается до тех пор, пока от пользователя не будет получен ввод, в отличие от клиентской стороны, которая, кажется, работает отлично.

Я думаю, что упускаю что-то совершенно очевидное, но потерял несколько часов назад, и ему бы очень хотелось, если бы кто-то мог помочь мне увидеть ошибку в моих путях!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...