python实现的聊天室(一)

    技术2022-07-10  81

    python实现的聊天室(一)

    1、前言

    我们学习了简单的Python TCP Socket 编程,通过分别写服务端和客户端的代码了解基本的 Python Socket 编程模型。本文再通过一个例子来加强一下对 Socket 编程的理解。   首先要学习一下 Python 中实现异步 I/O 的一个函数 —— select。与前面文章使用多线程来并行处理多路 socket I/O相比,这里介绍的select 方法允许你响应不同 socket 的多个事件以及其它不同事件。例如你可以让 select 在某个 socket 有数据到达时,或者当某个 socket 可以写数据时,又或者是当某个 socket 发生错误时通知你,好处是你可以同时响应很多 socket 的多个事件。   Python 中使用 list 来表示我们监控的文件描述符,当有事件到达时,返回的也是文件描述符的 list,表示这些文件有事件到达。select 方法的三个参数都是 list 类型,分别代表读事件、写事件、错误事件,同样方法返回值也是三个 list,包含的是哪些事件(读、写、异常)满足了。

    2、需求分析

    我们要实现的是简单的聊天室的例子,就是允许多个人同时一起聊天,每个人发送的消息所有人都能接收到,类似于 QQ 群的功能,而不是点对点的 QQ 好友之间的聊天。

    我们要实现的分为两部分:

    服务器:负责与用户建立 Socket 连接,并将某个用户发送的消息广播到所有在线的用户。用户聊天客户端,可以输入聊天的内容并发送,同时可以显示其他用户的消息记录。

    3、服务端实现

    import socket,select,thread; host=socket.gethostname() port=5963 addr=(host,port) inputs=[] fd_name={} def who_in_room(w): name_list=[] for k in w: name_list.append(w[k]) return name_list def conn(): print 'runing' ss=socket.socket() ss.bind(addr) ss.listen(5) return ss def new_coming(ss): client,add=ss.accept() print 'welcome %s %s' % (client,add) wel='''''welcome into the talking room . please decide your name.....''' try: client.send(wel) name=client.recv(1024) inputs.append(client) fd_name[client]=name nameList="Some people in talking room, these are %s" % (who_in_room(fd_name)) client.send(nameList) except Exception,e: print e def server_run(): ss=conn() inputs.append(ss) while True: r,w,e=select.select(inputs,[],[]) for temp in r: if temp is ss: new_coming(ss) else: disconnect=False try: data= temp.recv(1024) data=fd_name[temp]+' say : '+data except socket.error: data=fd_name[temp]+' leave the room' disconnect=True if disconnect: inputs.remove(temp) print data for other in inputs: if other!=ss and other!=temp: try: other.send(data) except Exception,e: print e del fd_name[temp] else: print data for other in inputs: if other!=ss and other!=temp: try: other.send(data) except Exception,e: print e if __name__=='__main__': server_run()

    4、客户端实现

    import socket,select,threading,sys; host=socket.gethostname() addr=(host,5963) def conn(): s=socket.socket() s.connect(addr) return s def lis(s): my=[s] while True: r,w,e=select.select(my,[],[]) if s in r: try: print s.recv(1024) except socket.error: print 'socket is error' exit() def talk(s): while True: try: info=raw_input() except Exception,e: print 'can\'t input' exit() try: s.send(info) except Exception,e: print e exit() def main(): ss=conn() t=threading.Thread(target=lis,args=(ss,)) t.start() t1=threading.Thread(target=talk,args=(ss,)) t1.start() if __name__=='__main__': main()

    5、运行效果

    运行时先启动服务端,再运行客户端。客户端运行后,命令行输入昵称,服务端会打印客户端IP及port信息,表明成功进入聊天室。当客户端关闭,表明该用户退出聊天室,服务器会转发该用户退出消息到各个客户端。  [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NWeyAuRT-1593526706590)(http://odsh9s4s2.bkt.clouddn.com/mychatserver.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hlvbe3xq-1593526706593)(http://odsh9s4s2.bkt.clouddn.com/mychatclientA.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CbQxcf64-1593526706595)(http://odsh9s4s2.bkt.clouddn.com/mychatclientB.png)]

    6、参考链接

    http://www.cnblogs.com/hazir/p/python_chat_room.html 链接

    http://www.cnblogs.com/hazir/p/python_chat_room.html

    Processed: 0.009, SQL: 9