0

I'm working on a threading server in Python but I'm running into problems with one connection blocking. When I make the first connection, it sleeps and then I don't get anything back on the second connection to the server until the first is done sleeping. Any thoughts on what I'm doing wrong?

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 Answers 2

4

It blocks because you're joining your new thread (and all the others) after each new connection is established. join blocks until the thread terminates, so only call it when you actually want to wait until the thread is done.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! This is awesome. I swear I didn't get an email on this before.
1

Based on @Steve Trout's insight -- here is the modified code. It starts a thread when a client connects, but doesn't join until the end of the server. It also has more extensive logging.

source

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

1 Comment

Thanks - I had no idea about join blocking on threads. This code looks much cleaner than what I had.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.