2017-09-10 7 views
0

私は、クライアントからの複数の接続を受け入れる必要があり、特定の優先度でいくつかの時間がかかる可能性のある命令を実行し、タスクが完了したら各クライアントに応答します。 私は実際に何かをする前に、これを実現するために、これの基本的な実装を書こうとしました。キューを持つPythonマルチクライアントサーバ

connオブジェクトをキューアイテムに渡して送信することで達成しようとしたタスクが完了したときにのみクライアントに返信したいのですが、問題は最初のタスクを実行するときです(2つ以上のクライアントが接続されており、回答が保留中であると仮定して)、サーバーはすべてのクライアントに応答しました。

コード:

import socket 
from threading import Thread 
import Queue 
import time 
import logging 

logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-9s) %(message)s',) 

BUFFER_SIZE = 20 
commands_queue = Queue.PriorityQueue(BUFFER_SIZE) 

class Command(object): 
    def __init__(self, priority, data, conn): 
     self.priority = priority 
     self.data = data 
     self.conn = conn 

    def __cmp__(self, other): 
     return cmp(self.priority, other.priority) 


class CommandsThread(Thread): 
    def __init__(self, group=None, target=None, name=None, 
       args=(), kwargs=None, verbose=None): 
     Thread.__init__(self) 
     self.target = target 
     self.name = name 


    def run(self): 
     while True: 
      if not commands_queue.empty(): 
       command = commands_queue.get() 
       logging.debug("Queueing data: " + command.data) 
       time.sleep(3) 
       logging.debug("Finshed queue: " + command.data) 
       command.conn.send("Done: " + command.data) # echo 

# Multithreaded Python server : TCP Server Socket Thread Pool 
class ClientThread(Thread): 
    def __init__(self, ip, port): 
     Thread.__init__(self) 
     self.ip = ip 
     self.port = port 
     print "[+] New server socket thread started for " + ip + ":" + str(port) 

    def run(self): 
     while True: 
      data = conn.recv(2048) 
      print "Server received data:", data 
      if not commands_queue.full(): 
       if data.startswith("a"): 
        commands_queue.put(Command(1, data, conn)) 
       else: 
        commands_queue.put(Command(2, data, conn)) 
       # conn.send("Done: " + data) # echo 


# Multithreaded Python server : TCP Server Socket Program Stub 
TCP_IP = '0.0.0.0' 
TCP_PORT = 2004 


tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
tcpServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
tcpServer.bind((TCP_IP, TCP_PORT)) 
threads = [] 

c = CommandsThread(name='commands') 
c.start() 
threads.append(c) 

while True: 
    tcpServer.listen(4) 
    print "Multithreaded Python server : Waiting for connections from TCP clients..." 
    (conn, (ip, port)) = tcpServer.accept() 
    newthread = ClientThread(ip, port) 
    newthread.start() 
    threads.append(newthread) 

for t in threads: 
    t.join() 

私は、ClientThread.run内、終了した後、CommandsThread内でそれをやってなくても、その関数内の回答を送信するために置かれているコマンドを待っていることは良い解決策になると思いましたこの特定のコマンドが完了するのを待つ方法については、Web上で見つけることができません。

感謝:)

答えて

0

ClientThreadでCONNのPARAMを作成して試してみて、それへの新しい接続を渡します。新しいコマンドをキューに入れると、connの代わりにself.connを渡します。

あなたのコードをpython3で試してみましたが、私の提案が改善され、うまくいきました。

サーバー(python2):

import socket 
from threading import Thread 
import Queue 
import time 
import logging 

logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-9s) %(message)s',) 

BUFFER_SIZE = 20 
commands_queue = Queue.PriorityQueue(BUFFER_SIZE) 

class Command(object): 
    def __init__(self, priority, data, conn): 
     self.priority = priority 
     self.data = data 
     self.conn = conn 

    def __cmp__(self, other): 
     return cmp(self.priority, other.priority) 


class CommandsThread(Thread): 
    def __init__(self, group=None, target=None, name=None, 
       args=(), kwargs=None, verbose=None): 
     Thread.__init__(self) 
     self.target = target 
     self.name = name 


    def run(self): 
     while True: 
      if not commands_queue.empty(): 
       command = commands_queue.get() 
       logging.debug("Queueing data: " + command.data) 
       time.sleep(3) 
       logging.debug("Finshed queue: " + command.data) 
       command.conn.send("Done: " + command.data) # echo 

# Multithreaded Python server : TCP Server Socket Thread Pool 
class ClientThread(Thread): 
    def __init__(self, conn, ip, port): 
     Thread.__init__(self) 
     self.conn = conn 
     self.ip = ip 
     self.port = port 
     print "[+] New server socket thread started for " + ip + ":" + str(port) 

    def run(self): 
     while True: 
      data = conn.recv(2048) 
      print "Server received data:", data 
      if not commands_queue.full(): 
       if data.startswith("a"): 
        commands_queue.put(Command(1, data, self.conn)) 
       else: 
        commands_queue.put(Command(2, data, self.conn)) 
       # conn.send("Done: " + data) # echo 


# Multithreaded Python server : TCP Server Socket Program Stub 
TCP_IP = '0.0.0.0' 
TCP_PORT = 2004 


tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
tcpServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
tcpServer.bind((TCP_IP, TCP_PORT)) 
threads = [] 

c = CommandsThread(name='commands') 
c.start() 
threads.append(c) 

while True: 
    tcpServer.listen(4) 
    print "Multithreaded Python server : Waiting for connections from TCP clients..." 
    (conn, (ip, port)) = tcpServer.accept() 
    newthread = ClientThread(ip, port) 
    newthread.start() 
    threads.append(newthread) 

for t in threads: 
    t.join() 

クライアント(python2):あなたのようなのparamとしてCONN置く

import socket 

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
host = "127.0.0.1" 
port = 2004 
sock.connect((host,port)) 
while True: 
    data = raw_input("message: ") 
    sock.send(data) 
    while True: 
     print("response: ", sock.recv(1024)) 
+0

が提案されてきたが、それを解決:)多くの感謝を行います – Jonathan

関連する問題