2017-09-10 3 views
0

J'ai un serveur, qui devrait accepter plusieurs connexions des clients, exécuter des ordres qui peuvent prendre des temps, dans une priorité spécifique, et répondre à chaque client quand sa tâche est terminée. J'ai essayé d'écrire une implémentation de base de ceci, pour la faire fonctionner avant qu'elle ne fasse quelque chose.Python Multipleclient Server avec files d'attente

Je ne veux répondre au client qu'une fois sa tâche terminée, ce que j'ai essayé de faire en passant l'objet conn à l'élément de la file et en l'envoyant, le problème est que lors de l'exécution de la première tâche client connecté (en supposant que j'ai 2 clients ou plus qui sont connectés, en attente de réponse), le serveur a répondu à tous les clients.

Le code:

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

Je pensais que l'intérieur ClientThread.run, en attendant la commande qui a été mis à la fin, puis envoyer la réponse dans cette fonction sans le faire à l'intérieur du CommandsThread sera une bonne solution, mais je ne peux pas trouver sur le web comment attendre que cette commande spécifique soit terminée.

Merci :)

Répondre

0

Essayez de créer conn à ClientThread et param passant nouvelle connexion à elle. Et quand vous mettez une nouvelle commande à la file d'attente - passez self.conn au lieu de conn.

J'ai essayé votre code sur python3 avec mes suggestions d'améliorations et cela a bien fonctionné.

Server (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() 

client (python2):

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

Mettre conn comme vous avez comme param suggéré ne le résoudre :) merci beaucoup – Jonathan