几乎在学习,使用任何一种编程语言的时候,关于套接字的练习从来都不会少,尤其是会写一些局域网的通信的东西,所以书上的这个项目刚好可以练习一下套接字编程。
这个练习的整体思路首先有一个聊天的服务器,这个服务器的功能主要是提供客户端套接字的连接,存储每个客户端的连接,处理每个连接发送的消息,解析客户端发送的数据。就这些,至于客户端方面不需要写代码,用系统的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基础教程项目五之虚拟茶话会