用Python线程化套接字服务器

时间:2014-07-31 21:10:20

标签: python multithreading sockets

我正在使用Python中的线程服务器,但我遇到了一个连接阻塞问题。当我进行第一次连接时,它会休眠,然后在第二次连接到服务器之前我没有得到任何回复,直到第一次连接完成。对我做错了什么的想法?

import socket, ssl, time, threading

def test_handler(conn):
    print "sleeping 10 seconds"
    time.sleep(10)
    conn.write("done sleeping")
    return 0


class ClientThread(threading.Thread):
    def __init__(self, connstream):
        threading.Thread.__init__(self)
        self.conn = connstream        

    def run(self):
        test_handler(self.conn)


threads = []
bindsocket = socket.socket()
bindsocket.bind(('0.0.0.0', 10023))
bindsocket.listen(10)

while True:
    newsocket, fromaddr = bindsocket.accept()
    connstream = ssl.wrap_socket(newsocket,
                                 server_side=True,
                                 certfile="server.crt",
                                 keyfile="server.key",
                                 ssl_version=ssl.PROTOCOL_TLSv1)
    try:
        c = ClientThread(connstream)
        c.start()
        threads.append(c)
    finally:
        for t in threads:
            t.join()

2 个答案:

答案 0 :(得分:4)

它会阻止因为您在建立每个新连接后join {{1}}新线程(以及所有其他线程)。 join阻塞直到线程终止,所以只有在你真的想等到线程完成时才调用它。

答案 1 :(得分:1)

基于@Steve Trout的见解 - 这是修改后的代码。它在客户端连接时启动一个线程,但在服务器结束之前不会join。它还有更广泛的日志记录。

import logging, socket, ssl, sys, time, threading

logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)-4s %(threadName)s %(message)s", 
    datefmt="%H:%M:%S",
    stream=sys.stderr,
)

def test_handler(conn):
    logging.info("sleeping 1 second")
    time.sleep(1)
    conn.send("done sleeping\n")
    return 0


class ClientThread(threading.Thread):
    def __init__(self, connstream):
        threading.Thread.__init__(self)
        self.conn = connstream        

    def run(self):
        test_handler(self.conn)

def main():
    port = 10023
    bindsocket = socket.socket()
    bindsocket.bind(('0.0.0.0', port))
    bindsocket.listen(10)

    logging.info('listening on port %d', port)
    while True:
        newsocket, fromaddr = bindsocket.accept()
        logging.info('connect from %s', fromaddr)
        connstream = newsocket
        if 0:
            connstream = ssl.wrap_socket(
                newsocket,
                server_side=True,
                certfile="server.crt",
                keyfile="server.key",
                ssl_version=ssl.PROTOCOL_TLSv1)
        ClientThread(connstream).start()

    logging.info('stop')

if __name__=='__main__':
    main()

    # make sure all threads are done
    for th in threading.enumerate():
        if th != threading.current_thread():
            th.join()