Make Python Socket Server More Efficient

Posted by BenMills on Stack Overflow See other posts from Stack Overflow or by BenMills
Published on 2010-03-14T18:31:12Z Indexed on 2010/03/14 18:55 UTC
Read the original article Hit count: 533

Filed under:
|
|

I have very little experience working with sockets and multithreaded programming so to learn more I decided to see if I could hack together a little python socket server to power a chat room. I ended up getting it working pretty well but then I noticed my server's CPU usage spiked up over 100% when I had it running in the background.

Here is my code in full: http://gist.github.com/332132

I know this is a pretty open ended question so besides just helping with my code are there any good articles I could read that could help me learn more about this?

My full code:

import select 
import socket 
import sys
import threading 
from daemon import Daemon

class Server: 
def __init__(self): 
    self.host = '' 
    self.port = 9998 
    self.backlog = 5 
    self.size = 1024 
    self.server = None 
    self.threads = []
    self.send_count = 0

def open_socket(self): 
    try: 
        self.server = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) 
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server.bind((self.host,self.port)) 
        self.server.listen(5) 
        print "Server Started..."
    except socket.error, (value,message): 
        if self.server: 
            self.server.close() 
        print "Could not open socket: " + message 
        sys.exit(1) 

def remove_thread(self, t):
    t.join()

def send_to_children(self, msg):
    self.send_count = 0
    for t in self.threads:
        t.send_msg(msg)
    print 'Sent to '+str(self.send_count)+" of "+str(len(self.threads))

def run(self): 
    self.open_socket() 
    input = [self.server,sys.stdin] 
    running = 1 
    while running: 
        inputready,outputready,exceptready = select.select(input,[],[]) 

        for s in inputready: 
            if s == self.server: 
                # handle the server socket 
                c = Client(self.server.accept(), self) 
                c.start() 
                self.threads.append(c)
                print "Num of clients: "+str(len(self.threads))

    self.server.close() 
    for c in self.threads: 
        c.join() 

class Client(threading.Thread): 
def __init__(self,(client,address), server): 
    threading.Thread.__init__(self) 
    self.client = client 
    self.address = address 
    self.size = 1024
    self.server = server
    self.running = True

def send_msg(self, msg):
    if self.running:
        self.client.send(msg)
        self.server.send_count += 1

def run(self):
    while self.running: 
        data = self.client.recv(self.size) 
        if data:
            print data
            self.server.send_to_children(data)
        else: 
            self.running = False
            self.server.threads.remove(self)
            self.client.close()

"""
Run Server
"""

class DaemonServer(Daemon):
def run(self):
    s = Server()
    s.run()

if __name__ == "__main__": 
d = DaemonServer('/var/servers/fserver.pid')
if len(sys.argv) == 2:
    if 'start' == sys.argv[1]:
        d.start()
    elif 'stop' == sys.argv[1]:
        d.stop()
    elif 'restart' == sys.argv[1]:
        d.restart()
    else:
        print "Unknown command"
        sys.exit(2)
    sys.exit(0)
else:
    print "usage: %s start|stop|restart" % sys.argv[0]
    sys.exit(2)

© Stack Overflow or respective owner

Related posts about python

Related posts about sockets