Python实现web聊天室,,使用Python模块


使用Python模块中的select模块实现web聊天室功能

select模块

Python中的select模块专注于I/O多路复用,提供了select poll epoll三个方法(其中后两个在Linux中可用,windows仅支持select),另外也提供了kqueue方法(freeBSD系统)


参数: 可接受四个参数(前三个必须)

rlist: wait until ready for reading

wlist: wait until ready for writing

xlist: wait for an “exceptional condition”

timeout: 超时时间


select方法:

每次调用slect都要将所有的fd拷贝到内核空间(每次都要拷贝),导致效率下降

每次调用slect都要将所有的fd拷贝到内核空间(每次都要拷贝),导致效率下降

监听的的实现是通过遍历所有的fd,(遍历消耗的时间消耗多)判断是否有数据访问

最大连接数(input中放的文件描述符数量1024)

pull方法:

最大连接数没有限制了,除此之外和select一样。使用较少

epull方法:

内部通过3个函数实现(select是其中一个)

第一个函数:
创建epoll句柄,把所有的fd拷贝到内核空间,只需要拷贝一次

第二个函数: 回调函数
某一个函数或者动作成功完成后,会自动触发一个函数为所有的fd绑定一个回调函数,一旦有数据访问,触发改回调函数,回调函数把fd放到链表中。(只要有活动,把fd放到链表中,动态监听)这样就提高了效率。例子:交试卷

第三个函数,判断链表是否为空


server端代码

#/usr/bin/envpython#-*-coding:utf-8-*-importsocketimportselect#封装classSelectServer(object):#定义主函数def__init__(self,host,port,backlog):self.host=hostself.port=portself.address=(host,port)self.backlog=backlogself.server=Noneself.socketList=list()def_initSocket(self):self.server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)self.server.bind(self.address)self.server.listen(self.backlog)self.socketList.append(self.server)print("chatroomhasstart!")while1:rlist,wlist,elist=select.select(self.socketList,[],[])forrinrlist:ifr==self.server:serverConn,clienAddr=self.server.accept()self.socketList.append(serverConn)print("{0}进入了房间".format(clienAddr))self.broadcast(r,"{0}进入了房间".format(clienAddr))else:try:data=r.recv(2048)ifdata:print("{0}:{1}".format(clienAddr,data))self.broadcast(r,"{0}:{1}".format(clienAddr,data))exceptExceptionase:self.broadcast(r,"{0}下线".format(clienAddr))print("{0}下线".format(clienAddr))r.close()self.socketList.remove(r)self.server.close()#定义广播函数defbroadcast(self,r,data):foriinself.socketList:ifi!=randi!=self.server:try:i.sendall(data)except:i.close()self.socketList.remove(i)#定义main函数defmain():selectServer=SelectServer(host="192.168.154.131",port=9999,backlog=5)selectServer._initSocket()if__name__=='__main__':main()


client端代码

#/usr/bin/envpython#-*-coding:utf-8-*-importsocket,select,string,sysimporttime#mainfunctionif__name__=="__main__":host="192.168.154.131"port=9999s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.settimeout(2)try:s.connect((host,port))except:print('Unabletoconnect')sys.exit()print('Connectedtoremotehost.Startsendingmessages')while1:rlist=[sys.stdin,s]read_list,write_list,error_list=select.select(rlist,[],[])forsockinread_list:ifsock==s:data=sock.recv(2048)ifnotdata:continueelse:sys.stdout.write(data)else:msg=raw_input("我说:")s.sendall(msg)


Python实现web聊天室

评论关闭