#!/usr/bin/python import socket, select class ChatServer: def __init__( self, port ): self.port = port self.srvsock = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) self.srvsock.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 ) self.srvsock.bind( ('', port ) ) self.srvsock.listen( 5 ) self.descriptors = [ self.srvsock ] print 'ChatServer start on port %s' % port def run( self ): while 1: #await an event on a readable socket descriptor ( sread, swrite, sexec ) = select.select( self.descriptors, [], [] ) #iterate through the tagged read descriptor for sock in sread: #received a connect to the server (listening) socket if sock == self.srvsock: self.accept_new_connection() else: #received something on a client socket str = sock.recv( 6042 ) #check to see if the peer socket closed host, port = sock.getpeername() if str == '': print 'stopping [%s:%s]\r\n' % ( host, port ) str = '\033[1;31mClient left %s:%s\033[1;m\r\n' % ( host, port ) self.broadcast_string( str, sock ) sock.close() self.descriptors.remove( sock ) elif '\username' in str: self.set_username( str, sock, port ) else: newstr = '\033[1;34m[user:%s] %s\033[1;m' % ( port, str ) self.broadcast_string( newstr, sock ) def broadcast_string( self, str, omit_sock ): for sock in self.descriptors: if sock != self.srvsock and sock != omit_sock: sock.send( str ) print str def accept_new_connection( self ): newsock, ( remhost, remport ) = self.srvsock.accept() self.descriptors.append( newsock ) newsock.send("\033[1;32mYou are now connected to the Poseidon chat server.\r\nPlease set a username by entering the syntax '\username ' followed by your chosen username.\033[1;m\r\n") str = '\033[1;33mClient joined %s:%s\033[1;m\r\n' % ( remhost, remport ) self.broadcast_string( str, newsock ) def set_username( self, str, sock, port ): username = str[ str.find(' ')+1: ] sock.append( {'username': username} ) str = "[user:%s] now known as %s" % ( port, username ) sock.send( str ) self.broadcast_string( str ) if __name__ == "__main__": myServer = ChatServer( 2626 ).run()