#!/usr/bin/python # First the server """ A basic, multiclient 'chat server' using Python's select module with interrupt handling. Entering any line of input at the terminal will exit the server. """ import select import socket import sys import signal from communication import send, receive import threading import GlobalVariables import time BUFSIZ = 1024 class CommServer(threading.Thread): """ Simple server using select """ def __init__(self, port=3490, backlog=5): self.clients = 0 # Client map self.clientmap = {} # Output socket list self.outputs = [] self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.server.bind(('',port)) print 'SERVER: Listening to port',port,'...' self.server.listen(backlog) # Trap keyboard interrupts #signal.signal(signal.SIGINT, self.sighandler) threading.Thread.__init__(self) #def sighandler(self, signum, frame): # if(GlobalVariables.UserInput=='exit' or GlobalVariables.UserInput=='EXIT'): # running=0 # for o in self.outputs: # o.close() # # self.server.close() # print "TEST" # Close the server # print 'SERVER: Shutting down server...' # Close existing client sockets # for o in self.outputs: # o.close() # self.server.close() def getname(self, client): # Return the printable name of the # client, given its socket... info = self.clientmap[client] host, name = info[0][0], info[1] return '@'.join((name, host)) def run(self): inputs = [self.server,sys.stdin] self.outputs = [] running = 1 while running: time.sleep(0.01) if(GlobalVariables.UserInput=='exit' or GlobalVariables.UserInput=='EXIT'): running=0 try: inputready,outputready,exceptready = select.select(inputs, self.outputs, []) except select.error, e: break except socket.error, e: break for s in inputready: if s == self.server: # handle the server socket client, address = self.server.accept() print 'SERVER: got connection %d from %s' % (client.fileno(), address) # Read the login name cname = receive(client).split('NAME: ')[1] # Compute client name and send back self.clients += 1 send(client, 'FROM SERVER: CLIENT: ' + str(address[0])) inputs.append(client) self.clientmap[client] = (address, cname) # Send joining information to other clients msg = '\nFROM SERVER: (Connected: New client (%d) from %s)' % (self.clients, self.getname(client)) for o in self.outputs: # o.send(msg) send(o, msg) self.outputs.append(client) #elif s == sys.stdin: # handle standard input # junk = sys.stdin.readline() # if (junk[:-1]=='exit' or junk[:-1]=='EXIT' ): # running = 0 # Close the server # print 'SERVER: Shutting down server...' # # Close existing client sockets # for o in self.outputs: # o.close() elif s!=sys.stdin: # handle all other sockets try: # data = s.recv(BUFSIZ) data = receive(s) if data: # Send as new client's message... msg = 'SERVER: You sent: >> ' + data GlobalVariables.UserInput=data print "SERVER: recv data: "+data for o in self.outputs: send(o, msg) if(GlobalVariables.UserInput=='exit' or GlobalVariables.UserInput=='EXIT'): running=0 # Send data to all except ourselves else: print 'SERVER: %d hung up' % s.fileno() self.clients -= 1 s.close() inputs.remove(s) self.outputs.remove(s) # Send client leaving information to others msg = 'SERVER: \n(Hung up: Client from %s)' % self.getname(s) for o in self.outputs: # o.send(msg) send(o, msg) except socket.error, e: # Remove inputs.remove(s) self.outputs.remove(s) print 'SERVER: Shutting down server...' # Close existing client sockets for o in self.outputs: o.close() self.server.close() #def run(self): # self.serve() if __name__ == "__main__": commServer=CommServer(3491,5) commServer.start()