具有队列的Python Multipleclient服务器

时间:2017-09-10 08:29:28

标签: python multithreading sockets queue

我有一个服务器,它应该接受来自客户端的多个连接,执行可能需要一些时间,特定优先级的命令,并在任务完成时响应每个客户端。 我试图写一个这个的基本实现,以使它在它实际做某事之前工作。

我只想在完成任务时回复客户端,我试图通过将ClientThread.run对象传递给队列项并通过它发送来实现,问题在于执行任务时从第一个连接的客户端(假设我有2个或更多连接的客户端,等待回答),服务器响应所有客户端。

代码:

CommandsThread

我认为在// ==UserScript== // @name _ChromeC // @include *//stackoverflow.com/* // @require https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js // @require https://gist.github.com/raw/2625891/waitForKeyElements.js // @grant GM_addStyle // ==/UserScript== /*- The @grant directive is needed to work around a major design change introduced in GM 1.0. It restores the sandbox. */ waitForKeyElements ("#interestingTags a", actionFunction); function actionFunction (jNode) { var clickEvent = document.createEvent ('MouseEvents'); clickEvent.initEvent ('click', true, true); jNode[0].dispatchEvent (clickEvent); } 内部,等待已经完成的命令,然后在function saveToDatabase(val) { var datas = 321; $.ajax({ url : base_url()+"/Update", type : "POST", dataType : "json", data : {datas:data}, success : function(data) { // do something alert("pass"); }, error : function(data) { // do something alert("fail"); } }); 内部发送该函数内的答案将是一个很好的解决方案,但我可以在网上找不到如何等待这个特定命令完成。

谢谢:)

1 个答案:

答案 0 :(得分:0)

尝试在ClientThread上创建conn param并将新连接传递给它。当你把新命令放到队列时 - 传递self.conn而不是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):

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