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
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.
1 Comment
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()