2016-11-06 4 views
0

私は多くのクライアント(thenewbostonのpythonリバースシェルチュートリアルから)を扱うためのサーバーを実装しようとしています。私はまったく同じコードを持っていますが、スクリプトを実行すると、queue.join()でスタックされます。それを動作させるには?私はそれを把握することができません。ここでPythonスクリプトがqueue.join()にスタックされました

(1ながら)あなたはACCEPT_CONNECTIONS彼らは戻っていないstart_turtleで無限ループ(トゥルー中)を使用しておりますので、コード

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() 
+0

「つぶれて」とはどういう意味ですか?サーバーの性質は、要求を受け取るまでアイドル状態に留まり、join()関数はすべてのスレッドをメインスレッドに参加させることを意味します。完了したら_これは正常な動作ではありませんか? – zenlc2000

+0

stuck私は、スレッドが実行されていないことを意味します。 queue.join()の後にprint( "Here")をタイプしても、実行されていないとします。しかし、join()の前に置くと、それは印刷されます。つまり、それはqueue.join()を通過していません。 – Beginner1111

答えて

0

です。 funcを返さないので、の作業は、queue.task_done()を呼び出すことはありません。

私はあなたが以下のいずれかを実行する必要が怖い:

    は両方 start_turtleACCEPT_CONNECTIONS並列プロセスやスレッドでを開始
  1. queue.task_done()を呼び出してください。

たとえば、パラメータとしてキューを含めて、無限ループを開始する前に呼び出すことができます(2番目のオプション)。あなたの労働者が実際に開始されませんでしたので、あなたは、スレッドのstartメソッドを呼び出すことはありませんあなたcreate_workersで

一方
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 

、。 おそらくこれはタイプミスです。

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 
関連する問題