#!/usr/bin/env python#Asynchronous Echo Server#filename:echoserver.pyimport socket,traceback,os,sys,selectclass stateclass: stdmask = select.POLLERR|select.POLLHUP|select.POLLNVAL def __init__(self,mastersock): #Initialize the state class self.p = select.poll() self.mastersock = mastersock self.watchread(mastersock.fileno()) self.buffers = {} self.sockets = {mastersock.fileno():mastersock} def fd2socket(self,fd): return self.sockets[fd] def watchread(self,fd): self.p.register(fd,select.POLLIN|self.stdmask) def watchwrite(self,fd): self.p.register(fd,select.POLLOUT|self.stdmask) def watchboth(self,fd): self.p.register(fd,select.POLLIN|select.POLLOUT|self.stdmask) def dontwatch(self,fd): self.p.unregister(fd) def newconn(self,sock): fd = sock.fileno() self.watchboth(fd) self.buffers[fd] = "Welcome to the echoserver,%s\n"%str(sock.getpeername()) self.sockets[fd] = sock def readevent(self,fd): try: self.buffers[fd] += self.fd2socket(fd).recv(4096) except: self.closeout(fd) self.watchboth(fd) def writeevent(self,fd): if not len(self.buffers[fd]): self.watchread(fd) return try: byteswritten = self.fd2socket(fd).send(self.buffers[fd]) except: self.closeout[fd] self.buffers[fd] = self.buffers[fd][byteswritten:] if not len(self.buffers[fd]): self.watchread(fd) def errorevent(self,fd): self.closeout(fd) def closeout(self,fd): self.dontwatch(fd) try: self.fd2socket(fd).close() except: pass del self.buffers[fd] del self.sockets[fd] def loop(self): while 1: result = self.p.poll() for fd,event in result: if fd == self.mastersock.fileno() and event == select.POLLIN: try: newsock,addr = self.fd2socket(fd).accept() newsock.setblocking(0) print "Got connection from",newsock.getpeername() self.newconn(newsock) except: pass elif event == select.POLLIN: self.readevent(fd) elif event == select.POLLOUT: self.writeevent(fd) else : self.errorevent(fd)host = ''port = 51423s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)s.bind((host,port))s.listen(1)s.setblocking(0)state = stateclass(s)state.loop()