首页 > 程序开发 > Web开发 > Python >

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

2013-04-23

Python教程 这里是第二十四章的源码,练习研究之用[python]#coding:utf8#python2.7 chatSer2.py#稍微复杂一点的聊天室服务器'''''用python启动服务 telnet连接之后就可以变成简单的聊天服...

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(&#39;Please login \nUse "login <nick>"\r\n&#39;)

def do_login(self, session, line):
name = line.strip()
#登陆时必须指定一个用户名
if not name:
session.push(&#39;Please enter a name\r\n&#39;)
elif name in self.server.users: #用户名不可重复 ?
session.push(&#39;The name "%s" is taken! \r\n&#39; %name)
session.push(&#39;Please try again.\r\n&#39;)
else:
session.name = name
session.enter(self.server.main_room)

class ChatRoom(Room):
&#39;&#39;&#39;&#39;&#39;
为多用户在一起聊天准备的房间
&#39;&#39;&#39;
def add(self, session):
#tell all new one come
self.broadcast(session.name +&#39; has entered the room. \r\n&#39;)
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 +&#39; has left the room \r\n&#39;)

def do_say(self, session, line):
self.broadcast(session.name+&#39;: &#39;+line+&#39;\r\n&#39;)

def do_look(self, session, line):
&#39;look who is in the room&#39;
session.push(&#39;The following are in this room: \r\n&#39;)
for other in self.sessions:
session.push(other.name+&#39;\r\n&#39;)

def do_who(self, session, line):
&#39;查看谁登陆过&#39;
session.push(&#39;The following are logged in: \r\n&#39;)
for name in self.server.users:
session.push(name+ &#39;\r\n&#39;)

class LogoutRoom(Room):
&#39;&#39;&#39;&#39;&#39;
为单个用户准备的房间,只用于将用户从服务器移除
&#39;&#39;&#39;

def add(self, session):
try:
del self.server.users[session.name]
except KeyError:
pass

class ChatSession(async_chat):
&#39;&#39;&#39;&#39;&#39;
单个会话,负责和用户通信
&#39;&#39;&#39;

def __init__(self, server, sock):
async_chat.__init__(self, sock)
self.server = server
self.set_terminator(&#39;\r\n&#39;)
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 = &#39;&#39;.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):
&#39;&#39;&#39;&#39;&#39;
只有一个房间的聊天服务器
&#39;&#39;&#39;

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__==&#39;__main__&#39;:
s = ChatServer(SERVERCONF,NAME)
try:
asyncore.loop()
except KeyboardInterrupt:
print &#39;server Exception ...quit&#39;


#coding:utf8
#python2.7 chatSer2.py
#稍微复杂一点的聊天室服务器
&#39;&#39;&#39;
用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

&#39;&#39;&#39;

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

HOST = &#39;&#39;
PORT = 50005
SERVERCONF = (HOST,PORT)
NAME = &#39;TestChat&#39;

class EndSession(Exception):
pass

class CommandHandler(object):
&#39;&#39;&#39;
命令解析类
&#39;&#39;&#39;

def unknown(self,session,cmd):
&#39;响应未知的命令&#39;
session.push(&#39;Unknown command:%s \r\n&#39; %cmd)

def handle(self,session,line):
&#39;处理从客户端发来的信息 解析命令和内容&#39;
if not line:
print &#39;please write a command...&#39;

if not line.strip():
print &#39;get a line :&#39;,line
return

parts = line.split(&#39; &#39;,1)
#命令分离
cmd = parts[0]
try:
line = parts[1].strip()
except IndexError:
line = &#39;&#39;
#调用相应的方法处理命令
meth = getattr(self, &#39;do_&#39;+cmd, None)
try:
#调用命令对应的方法
meth(session,line)
except TypeError:
self.unknown(session, cmd)

class Room(CommandHandler):
&#39;&#39;&#39;
包括一个或多个用户(会话)的泛型环境。负责处理基本的命令和广播
&#39;&#39;&#39;

def __init__(self,server):
self.server = server
self.sessions = []

def add(self, session):
&#39;add a user&#39;
self.sessions.append(session)

def remove(self,session):
&#39;a user leave&#39;
self.sessions.remove(session)

def broadcast(self,line):
&#39;give all session in the room a line&#39;
for session in self.sessions:
session.push(line)

def do_logout(self,session,line):
&#39;响应登出命令&#39;
raise EndSession

class LoginRoom(Room):
&#39;&#39;&#39;
为刚刚登陆的用户准备的房间
&#39;&#39;&#39;

def add(self,session):
Room.add(self, session)
self.broadcast(&#39;Welcome to %s \r\n&#39; %self.server.name)

def unknown(self, session, cmd):
session.push(&#39;Please login \nUse "login <nick>"\r\n&#39;)

def do_login(self, session, line):
name = line.strip()
#登陆时必须指定一个用户名
if not name:
session.push(&#39;Please enter a name\r\n&#39;)
elif name in self.server.users: #用户名不可重复 ?
session.push(&#39;The name "%s" is taken! \r\n&#39; %name)
session.push(&#39;Please try again.\r\n&#39;)
else:
session.name = name
session.enter(self.server.main_room)

class ChatRoom(Room):
&#39;&#39;&#39;
为多用户在一起聊天准备的房间
&#39;&#39;&#39;
def add(self, session):
#tell all new one come
self.broadcast(session.name +&#39; has entered the room. \r\n&#39;)
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 +&#39; has left the room \r\n&#39;)

def do_say(self, session, line):
self.broadcast(session.name+&#39;: &#39;+line+&#39;\r\n&#39;)

def do_look(self, session, line):
&#39;look who is in the room&#39;
session.push(&#39;The following are in this room: \r\n&#39;)
for other in self.sessions:
session.push(other.name+&#39;\r\n&#39;)

def do_who(self, session, line):
&#39;查看谁登陆过&#39;
session.push(&#39;The following are logged in: \r\n&#39;)
for name in self.server.users:
session.push(name+ &#39;\r\n&#39;)

class LogoutRoom(Room):
&#39;&#39;&#39;
为单个用户准备的房间,只用于将用户从服务器移除
&#39;&#39;&#39;

def add(self, session):
try:
del self.server.users[session.name]
except KeyError:
pass

class ChatSession(async_chat):
&#39;&#39;&#39;
单个会话,负责和用户通信
&#39;&#39;&#39;

def __init__(self, server, sock):
async_chat.__init__(self, sock)
self.server = server
self.set_terminator(&#39;\r\n&#39;)
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 = &#39;&#39;.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):
&#39;&#39;&#39;
只有一个房间的聊天服务器
&#39;&#39;&#39;

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__==&#39;__main__&#39;:
s = ChatServer(SERVERCONF,NAME)
try:
asyncore.loop()
except KeyboardInterrupt:
print &#39;server Exception ...quit&#39;



结果如图所示

\
相关文章
最新文章
热点推荐