python基础教程项目五之虚拟茶话会

  

几乎在学习,使用任何一种编程语言的时候,关于套接字的练习从来都不会少,尤其是会写一些局域网的通信的东西,所以书上的这个项目刚好可以练习一下套接字编程。

  

这个练习的整体思路首先有一个聊天的服务器,这个服务器的功能主要是提供客户端套接字的连接,存储每个客户端的连接,处理每个连接发送的消息,解析客户端发送的数据。就这些,至于客户端方面不需要写代码,用系统的telnet工具即可。

  

我觉得有了上面的分析,剩下的这个程序就没有什么说的了,当然,除了那两个把套接字封装的类之外。

  

自己使用python中的套接字类尝试这个编写了一个简单的通信程序,不过不知为什么,通信中总是出现意外。这段简单的代码如下:
  

  

server.py         进口套接字      mysocket=socket.socket (socket.AF_INET socket.SOCK_STREAM)   mysocket.bind (", 8888)   mysocket.listen (5)      而真正的:   连接,addr=mysocket.accept ()   revStr=connection.recv (1024)   连接。发送(“服务器:”+ revStr)   connection.close ()      之前      

clinet.py         进口套接字   导入的时间      clientsocket=socket.socket(插座。AF_INET socket.SOCK_STREAM)      clientsocket.connect (", 8888)   而真正的:   time . sleep (2)   clientsocket。发送(“你好the5fire”)   打印clientsocket.recv (1024)      clientsocket.close ()      之前      

这个程序出错的原因没有去细揪,因为python中提供了两个封装好的类来完成插座通信过程:asynchat中的async_chat和asyncore中的调度程序以及asyncore本身。前面的类是用来处理客户端同服务器的每一次会话,后面的类主要是用来提供插座连接服务,并且将每一个套接字连接都托管给前者(async_chat)来处理。

  

来看代码:

  

        从asyncore进口分配器   从asynchat进口async_chat   进口套接字,asyncore      端口=5005   NAME=' TestChat '      类EndSession(异常):通过      类CommandHandler:      def未知(自我,会话,cmd):   会话。推动(“未知的命令:% s \ r \ n ' % cmd)      def处理(自我、会话、线):   如果不是line.strip():返回      部分=线。分割(' ',1)   cmd=[0]部分   试一试:行=[1]部分.strip ()   除了IndexError:行="      冰毒=getattr(自我,do_ + cmd,无)      试一试:   甲安菲他明(会话,线)   除了TypeError:   self.unknown(会话,cmd)      教室(CommandHandler):      def __init__(自我、服务器):   自我。服务器=服务器   自我。会话=[]      def添加(自我、会话):   self.sessions.append(会话)      def删除(自我、会话):   self.sessions.remove(会话)      def广播(自我、线):   会话的self.sessions:   session.push(线)      def do_logout(自我、会话、线):   提高EndSession      类LoginRoom(室):      def添加(自我、会话):   Room.add(自我,会话)      自我。广播(欢迎来到%年代\ r \ n % self.server.name)      def未知(自我,会话,cmd):   会话。推动(请登录\ nUse“登录”\ r \ n”)      def do_login(自我、会话、线):   name=line.strip ()      如果没有名字:   会话。push(“请输入一个名称\ r \ n”)   elif self.server.users名称:   会话。推动(的名称“% s”。\ r \ n ' %的名字)   sessoin。push(“请再试一次。\ r \ n”)   其他:   session.name=名字   session.enter (self.server.main_room)      类聊天室(室):      def添加(自我、会话):   self.broadcast (session.name +”已经进入了房间。\ r \ n”)   self.server.users [session.name]=会话   房间。添加(自我,会话)      def删除(自我、会话):   房间。删除(自我,会话)      self.broadcast (session.name +”离开了房间。\ r \ n”)      def do_say(自我、会话、线):   self.broadcast (session.name +‘:’+线+“\ r \ n”)      def do_look(自我、会话、线):   会话。推动('下面是在这个房间里:\ r \ n”)   对于其他self.sessions:   session.push (other.name +“\ r \ n”)      def do_who(自我、会话、线):   会话。推动(“以下是登录:\ r \ n”)   在self.server.users名字:   会话。推动(名字+“\ r \ n”)      类LogoutRoom(室):      def添加(自我、会话):   试题:德尔self.server.users [session.name]   除了KeyError:通过      类ChatSession (async_chat):      def __init__(自我、服务器、袜子):   async_chat.__init__(自我,袜子)   自我。服务器=服务器   self.set_terminator (“\ r \ n”)   自我。data=https://www.yisu.com/zixun/[]   self.name=没有      self.enter (LoginRoom(服务器)      def输入(自我,房间):      试一试:   坏蛋=self.room   除了AttributeError:   通过   其他:cur.remove(自我)   自我。房间=room.add(自我)      def collect_incoming_data(自我、数据):   self.data.append(数据)      def found_terminator(自我):   行=" . join (self.data)   自我。data=https://www.yisu.com/zixun/[]   试一试:self.room。处理(自我,线)   除了EndSession:   self.handle_close ()      def handle_close(自我):   async_chat.handle_close(自我)   self.enter (LogoutRoom (self.server))      类ChatServer(调度程序):      def __init__(自我、港口、名称):   dispatcher.__init__(自我)   self.create_socket(套接字。AF_INET socket.SOCK_STREAM)   self.bind(端口)(“)   self.listen (5)   self.name=名字   自我。用户={}   自我。main_room=聊天室(自我)      def handle_accept(自我):   康涅狄格州,addr=self.accept ()   康涅狄格州ChatSession(自我)      if __name__==癬_main__”:   s=ChatServer(港口名称)   试一试:asyncore.loop ()   除了KeyboardInterrupt:打印      

python基础教程项目五之虚拟茶话会