频道栏目
首页 > 资讯 > Python > 正文

[Python-*-读书]Python基础教程--虚拟茶话会

13-04-23        来源:[db:作者]  
收藏   我要投稿

Python教程  这里是第二十四章的源码,练习研究之用


[python] 
#coding:utf8   
#python2.7 chatSer2.py  
#稍微复杂一点的聊天室服务器  
'''''
用python启动服务 telnet连接之后就可以变成简单的聊天服务器
第一次登陆:login name 
登出: logout
说话: say 
查看谁登陆过服务器:who 
查看同一个房间的人 : look 
 
简单例子:
telnet localhost 50005
Welcome to TestChat
login tianshi
diyu has entered the room.
nih
Unknown command: ih
say nihao
tianshi: nihao
diyu: niyehao
 
''' 
 
from asyncore import dispatcher  
from asynchat import async_chat 
import socket 
import asyncore 
 
HOST = '' 
PORT = 50005 
SERVERCONF = (HOST,PORT) 
NAME = 'TestChat' 
 
class EndSession(Exception): 
    pass  
 
class CommandHandler(object): 
    '''''
    命令解析类
    ''' 
     
    def unknown(self,session,cmd): 
        '响应未知的命令' 
        session.push('Unknown command:%s \r\n' %cmd) 
 
    def handle(self,session,line): 
        '处理从客户端发来的信息 解析命令和内容' 
        if not line: 
            print 'please write a command...' 
             
        if not line.strip():  
            print 'get a line :',line  
            return 
         
        parts = line.split(' ',1) 
        #命令分离  
        cmd = parts[0] 
        try: 
            line = parts[1].strip() 
        except IndexError: 
            line = '' 
        #调用相应的方法处理命令  
        meth = getattr(self, 'do_'+cmd, None) 
        try: 
            #调用命令对应的方法  
            meth(session,line) 
        except TypeError: 
            self.unknown(session, cmd) 
             
class Room(CommandHandler): 
    '''''
    包括一个或多个用户(会话)的泛型环境。负责处理基本的命令和广播
    ''' 
     
    def __init__(self,server): 
        self.server = server 
        self.sessions = [] 
         
    def add(self, session): 
        'add a user' 
        self.sessions.append(session) 
         
    def remove(self,session): 
        'a user leave' 
        self.sessions.remove(session) 
         
    def broadcast(self,line): 
        'give all session in the room a line' 
        for session in self.sessions: 
            session.push(line) 
         
    def do_logout(self,session,line): 
        '响应登出命令' 
        raise EndSession 
     
class LoginRoom(Room): 
    '''''
    为刚刚登陆的用户准备的房间
    ''' 
     
    def add(self,session): 
        Room.add(self, session) 
        self.broadcast('Welcome to %s \r\n' %self.server.name) 
         
    def unknown(self, session, cmd): 
        session.push('Please login \nUse "login <nick>"\r\n') 
         
    def do_login(self, session, line): 
        name = line.strip() 
        #登陆时必须指定一个用户名  
        if not name: 
            session.push('Please enter a name\r\n') 
        elif name in self.server.users: #用户名不可重复 ?  
            session.push('The name "%s" is taken! \r\n' %name) 
            session.push('Please try again.\r\n') 
        else: 
            session.name = name 
            session.enter(self.server.main_room) 
             
class ChatRoom(Room): 
    '''''
    为多用户在一起聊天准备的房间
    ''' 
    def add(self, session): 
        #tell all new one come  
        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) 
        #tell all the user logout  
        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): 
        'look who is in the 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): 
        '查看谁登陆过' 
        session.push('The following are logged in: \r\n') 
        for name in self.server.users: 
            session.push(name+ '\r\n') 
 
class LogoutRoom(Room): 
    '''''
    为单个用户准备的房间,只用于将用户从服务器移除
    ''' 
     
    def add(self, session): 
        try: 
            del self.server.users[session.name] 
        except KeyError: 
            pass  
         
class ChatSession(async_chat): 
    '''''
    单个会话,负责和用户通信
    ''' 
     
    def __init__(self, server, sock): 
        async_chat.__init__(self, sock) 
        self.server = server 
        self.set_terminator('\r\n') 
        self.data = [] 
        self.name = None 
        #所有会话从这里登入  
        self.enter(LoginRoom(server)) 
 
    def enter(self, room): 
        try:  
            cur = self.room 
        except AttributeError: 
            pass  
        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): 
    '''''
    只有一个房间的聊天服务器
    ''' 
     
    def __init__(self, serverconf, name): 
        dispatcher.__init__(self) 
        self.create_socket(socket.AF_INET,socket.SOCK_STREAM) 
        self.set_reuse_addr() #可以重用上一次的端口号  
        self.bind(SERVERCONF) 
        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(SERVERCONF,NAME) 
    try: 
        asyncore.loop() 
    except KeyboardInterrupt: 
        print 'server Exception ...quit' 
         
                      
         

#coding:utf8
#python2.7 chatSer2.py
#稍微复杂一点的聊天室服务器
'''
用python启动服务 telnet连接之后就可以变成简单的聊天服务器
第一次登陆:login name
登出: logout
说话: say
查看谁登陆过服务器:who
查看同一个房间的人 : look

简单例子:
telnet localhost 50005
Welcome to TestChat
login tianshi
diyu has entered the room.
nih
Unknown command: ih
say nihao
tianshi: nihao
diyu: niyehao

'''

from asyncore import dispatcher
from asynchat import async_chat
import socket
import asyncore

HOST = ''
PORT = 50005
SERVERCONF = (HOST,PORT)
NAME = 'TestChat'

class EndSession(Exception):
    pass

class CommandHandler(object):
    '''
    命令解析类
    '''
   
    def unknown(self,session,cmd):
        '响应未知的命令'
        session.push('Unknown command:%s \r\n' %cmd)

    def handle(self,session,line):
        '处理从客户端发来的信息 解析命令和内容'
        if not line:
            print 'please write a command...'
           
        if not line.strip():
            print 'get a line :',line
            return
       
        parts = line.split(' ',1)
        #命令分离
        cmd = parts[0]
        try:
            line = parts[1].strip()
        except IndexError:
            line = ''
        #调用相应的方法处理命令
        meth = getattr(self, 'do_'+cmd, None)
        try:
            #调用命令对应的方法
            meth(session,line)
        except TypeError:
            self.unknown(session, cmd)
           
class Room(CommandHandler):
    '''
    包括一个或多个用户(会话)的泛型环境。负责处理基本的命令和广播
    '''
   
    def __init__(self,server):
        self.server = server
        self.sessions = []
       
    def add(self, session):
        'add a user'
        self.sessions.append(session)
       
    def remove(self,session):
        'a user leave'
        self.sessions.remove(session)
       
    def broadcast(self,line):
        'give all session in the room a line'
        for session in self.sessions:
            session.push(line)
       
    def do_logout(self,session,line):
        '响应登出命令'
        raise EndSession
   
class LoginRoom(Room):
    '''
    为刚刚登陆的用户准备的房间
    '''
   
    def add(self,session):
        Room.add(self, session)
        self.broadcast('Welcome to %s \r\n' %self.server.name)
       
    def unknown(self, session, cmd):
        session.push('Please login \nUse "login <nick>"\r\n')
       
    def do_login(self, session, line):
        name = line.strip()
        #登陆时必须指定一个用户名
        if not name:
            session.push('Please enter a name\r\n')
        elif name in self.server.users: #用户名不可重复 ?
            session.push('The name "%s" is taken! \r\n' %name)
            session.push('Please try again.\r\n')
        else:
            session.name = name
            session.enter(self.server.main_room)
           
class ChatRoom(Room):
    '''
    为多用户在一起聊天准备的房间
    '''
    def add(self, session):
        #tell all new one come
        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)
        #tell all the user logout
        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):
        'look who is in the 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):
        '查看谁登陆过'
        session.push('The following are logged in: \r\n')
        for name in self.server.users:
            session.push(name+ '\r\n')

class LogoutRoom(Room):
    '''
    为单个用户准备的房间,只用于将用户从服务器移除
    '''
   
    def add(self, session):
        try:
            del self.server.users[session.name]
        except KeyError:
            pass
       
class ChatSession(async_chat):
    '''
    单个会话,负责和用户通信
    '''
   
    def __init__(self, server, sock):
        async_chat.__init__(self, sock)
        self.server = server
        self.set_terminator('\r\n')
        self.data = []
        self.name = None
        #所有会话从这里登入
        self.enter(LoginRoom(server))

    def enter(self, room):
        try:
            cur = self.room
        except AttributeError:
            pass
        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):
    '''
    只有一个房间的聊天服务器
    '''
   
    def __init__(self, serverconf, name):
        dispatcher.__init__(self)
        self.create_socket(socket.AF_INET,socket.SOCK_STREAM)
        self.set_reuse_addr() #可以重用上一次的端口号
        self.bind(SERVERCONF)
        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(SERVERCONF,NAME)
    try:
        asyncore.loop()
    except KeyboardInterrupt:
        print 'server Exception ...quit'
       
                    
       
结果如图所示

相关TAG标签
上一篇:如何修改linux主机名称
下一篇:#Python 核心编程网络协议编程 Email
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站