Python脚本卡在queue.join()上



我正试图实现一个服务器来处理许多客户端(从newboston python反向shell教程)。我有完全相同的代码,但当我运行脚本时,它会卡在queue.join()。如何让它发挥作用?我想不明白。

代码

import socket
import sys
import threading
from queue import Queue
NUMBER_OF_THREADS = 2
JOB_NUMBER = [1, 2]
queue = Queue()
all_connections = []
all_addresses = []
# thread 1
# create socket (allows two computers to connect)
def socket_create():
    try:
        global host # ip address of the server
        global port # port is to identify the kind of data
        global s
        host = ''
        port = 9999
        s = socket.socket()
    except socket.error as msg:
        print("Socket creation error: " + str(msg))
    return
# bind socket to port and wait for connection from client
def socket_bind():
    try:
        global host
        global port
        global s
        print("Binding socket to port: " + str(port))
        s.bind((host, port))
        s.listen(5)
        # 5 is the no. of conections that can be made before server starts     rejecting other requests  
    except socket.error as msg:
        print("Socket binding error: " + str(msg) + "n" + "Retrying...")
        socket_bind()
    return
# accept connections from multiple clients and save to list
def accept_connections():
    for c in all_connections:
        c.close()
    del all_connections[:]
    del all_addresses[:]
    while 1:
        try:
            conn, address = s.accept()
            conn.setblocking(1)
            all_connections.append(conn)
            all_addresses.append(address)
            print("nConnection has been establish: " + address[0])
        except:
            print("Error accepting connections")
    return
# thread 2
# custom command promt for sending commands remotely
def start_turtle():
    while True:
        cmd = input('turtle> ')
        if cmd == 'list':
            list_connections()
        elif 'select' in cmd:
            conn = get_target(cmd)
            if conn is not None:
                send_target_commands(conn)
        else:
            print("Command not recognized")
    return
# listing all the connections with indexing in the custom promt
def list_connections():
    results = ''
    for i, conn in enumerate(all_connections):
        try:
            conn.send(str.encode(' '))
            conn.recv(20480)
        except:
            del all_connections[i]
            del all_addresses[i]
            continue
        results += str(i) + '   ' + str(all_addresses[i][0]) + '   ' +      str(all_addresses[i][1]) + 'n'
    print('-----Clients-----' + 'n' + results)
    return
# select a target client
def get_target(cmd):
    try:
        target = cmd.replace('select ', '')
        target = int(target)
        conn = all_connections[target]
        print("You are now connected to " + str(all_addresses[target][0]))
        print(str(all_addresses[target][0]) + '> ', end="")
        return conn
    except:
        print("Not a valid selection")
        return None
    return
# connect with remote target client
def send_target_commands(conn):
    while True:
        try:
            cmd = input()
            if len(str.encode(cmd)) > 0:
                conn.send(str.encode(cmd))
                client_response = str(conn.recv(20480), "utf-8")
                print(client_response, end="")
            if cmd == "quit":
                break
        except:
            print("Connection was lost")
            break
    return
# create worker threads
def create_workers():
    for _ in range(NUMBER_OF_THREADS):
        t = threading.Thread(target=work)
        t.daemon = True
        t.start
    return
# do the next job in the queue (one handles connections, other sends commands)
def work():
    while True:
        x = queue.get()
        if x == 1:
            socket_create()
            socket_bind()
            accept_connections()
        if x == 2:
            start_turtle()
        queue.task_done()
    return
# create jobs for later extracting them and assigning them to the threads
def create_jobs():
    for x in JOB_NUMBER:
        queue.put(x)
    queue.join()
    return
def main():  
    create_workers()
    create_jobs()
if __name__ == '__main__':
    main()

由于您在start_turtle和(while 1)在accept_connections使用无限循环(当为True时),它们不会返回。由于它们不返回func work从不调用queue.task_done(),因此队列无法加入。

恐怕你需要做以下其中一件事:

  1. 在并行进程或线程中同时启动start_turtleaccept_connections
  2. 确保他们应该调用queue.task_done().

例如,您可以将queue作为参数包含,并在开始无限循环之前调用它(第二个选项)。

def work():
    while True:
    x = queue.get()
    if x == 1:
        socket_create()
        socket_bind()
        accept_connections(queue)  # call queue.task_done() there
    if x == 2:
        start_turtle(queue)  # call queue.task_done() in start_turtle
    return
def start_turtle(queue):
    queue.task_done()  # Join one item from the queue
    while True:
        cmd = input('turtle> ')
        if cmd == 'list':
            list_connections()
        elif 'select' in cmd:
            conn = get_target(cmd)
            if conn is not None:
                send_target_commands(conn)
        else:
            print("Command not recognized")
    return
另一方面,在你的create_workers中,你没有调用线程的start方法,所以你的worker并没有真正启动。也许这是一个打字错误。
def create_workers():
    for _ in range(NUMBER_OF_THREADS):
        t = threading.Thread(target=work)
        t.daemon = True
        # t.start  # Not starting the Thread
        t.start()  # You need to call the start method
    return

最新更新