⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listing24-6.py

📁 《Beginning Python--From Novice to Professional》 的源码
💻 PY
字号:
from asyncore import dispatcherfrom asynchat import async_chatimport socket, asyncorePORT = 5005NAME = 'TestChat'class EndSession(Exception): passclass CommandHandler:    """    Simple command handler similar to cmd.Cmd from the standard    library.    """    def unknown(self, session, cmd):        'Respond to an unknown command'        session.push('Unknown command: %s\r\n' % cmd)    def handle(self, session, line):        'Handle a received line from a given session'        if not line.strip(): return        # Split off the command:        parts = line.split(' ', 1)        cmd = parts[0]        try: line = parts[1].strip()        except IndexError: line = ''        # Try to find a handler:        meth = getattr(self, 'do_'+cmd, None)        try:            # Assume it's callable:            meth(session, line)        except TypeError:            # If it isn't, respond to the unknown command:            self.unknown(session, cmd)class Room(CommandHandler):    """    A generic environment that may contain one or more users    (sessions). It takes care of basic command handling and    broadcasting.    """    def __init__(self, server):        self.server = server        self.sessions = []    def add(self, session):        'A session (user) has entered the room'        self.sessions.append(session)    def remove(self, session):        'A session (user) has left the room'        self.sessions.remove(session)    def broadcast(self, line):        'Send a line to all sessions in the room'        for session in self.sessions:            session.push(line)    def do_logout(self, session, line):        'Respond to the logout command'        raise EndSessionclass LoginRoom(Room):    """    A room meant for a single person who has just connected.    """    def add(self, session):        Room.add(self, session)        # When a user enters, greet him/her:        self.broadcast('Welcome to %s\r\n' % self.server.name)    def unknown(self, session, cmd):        # All unknown commands (anything except login or logout)        # results in a prodding:        session.push('Please log in\nUse "login <nick>"\r\n')    def do_login(self, session, line):        name = line.strip()        # Make sure the user has entered a name:        if not name:            session.push('Please enter a name\r\n')        # Make sure that the name isn't in use:        elif name in self.server.users:            session.push('The name "%s" is taken.\r\n' % name)            session.push('Please try again.\r\n')        else:            # The name is OK, so it is stored in the session, and            # the user is moved into the main room.            session.name = name            session.enter(self.server.main_room)class ChatRoom(Room):    """    A room meant for multiple users who can chat with the others in    the room.    """    def add(self, session):        # Notify everyone that a new user has entered:        self.broadcast(session.name + ' has entered the room.\r\n')        self.server.users[session.name] = session        Room.add(self, session)    def remove(self, session):        Room.remove(self, session)        # Notify everyone that a user has left:        self.broadcast(session.name + ' has left the room.\r\n')    def do_say(self, session, line):        self.broadcast(session.name+': '+line+'\r\n')    def do_look(self, session, line):        'Handles the look command, used to see who is in a room'        session.push('The following are in this room:\r\n')        for other in self.sessions:            session.push(other.name + '\r\n')    def do_who(self, session, line):        'Handles the who command, used to see who is logged in'        session.push('The following are logged in:\r\n')        for name in self.server.users:            session.push(name + '\r\n')class LogoutRoom(Room):    """    A simple room for a single user. Its sole purpose is to remove    the user's name from the server.    """    def add(self, session):        # When a session (user) enters the LogoutRoom it is deleted        try: del self.server.users[session.name]        except KeyError: passclass ChatSession(async_chat):    """    A single session, which takes care of the communication with a    single user.    """    def __init__(self, server, sock):        async_chat.__init__(self, sock)        self.server = server        self.set_terminator("\r\n")        self.data = []        self.name = None        # All sessions begin in a separate LoginRoom:        self.enter(LoginRoom(server))    def enter(self, room):        # Remove self from current room and add self to        # next room...        try: cur = self.room        except AttributeError: pass        else: cur.remove(self)        self.room = room        room.add(self)    def collect_incoming_data(self, data):        self.data.append(data)    def found_terminator(self):        line = ''.join(self.data)        self.data = []        try: self.room.handle(self, line)        except EndSession:            self.handle_close()    def handle_close(self):        async_chat.handle_close(self)        self.enter(LogoutRoom(self.server))class ChatServer(dispatcher):    """    A chat server with a single room.    """    def __init__(self, port, name):        dispatcher.__init__(self)        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)        self.set_reuse_addr()        self.bind(('', port))        self.listen(5)        self.name = name        self.users = {}        self.main_room = ChatRoom(self)    def handle_accept(self):        conn, addr = self.accept()        ChatSession(self, conn)if __name__ == '__main__':    s = ChatServer(PORT, NAME)    try: asyncore.loop()    except KeyboardInterrupt: print

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -