支持 put all rem message one utf cti 访问
使用 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/env python
- #-*- coding:utf-8 -*-
- import socket
- importselect
- # 封装
- classSelectServer(object):
- # 定义主函数
- def __init__(self, host, port, backlog):
- self.host = host
- self.port = port
- self.address =(host, port)
- self.backlog = backlog
- self.server =None
- self.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("chat room has start!")
- while1:
- rlist, wlist, elist =select.select(self.socketList,[],[])
- for r in rlist:
- if r ==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)
- if data:
- print("{0}: {1}".format(clienAddr, data))
- self.broadcast(r,"{0}: {1}".format(clienAddr, data))
- exceptExceptionas e:
- self.broadcast(r,"{0}下线".format(clienAddr))
- print("{0}下线".format(clienAddr))
- r.close()
- self.socketList.remove(r)
- self.server.close()
- # 定义广播函数
- def broadcast(self, r, data):
- for i inself.socketList:
- if i != r and i !=self.server:
- try:
- i.sendall(data)
- except:
- i.close()
- self.socketList.remove(i)
- # 定义main函数
- def main():
- selectServer =SelectServer(host="192.168.154.131", port=9999, backlog=5)
- selectServer._initSocket()
- if __name__ =='__main__':
- main()
client 端代码
Python 实现 web 聊天室
- #/usr/bin/env python
- #-*- coding:utf-8 -*-
- import socket,select,string, sys
- import time
- # main function
- if __name__ =="__main__":
- host ="192.168.154.131"
- port =9999
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.settimeout(2)
- try:
- s.connect((host, port))
- except:
- print('Unable to connect')
- sys.exit()
- print('Connected to remote host. Start sending messages')
- while1:
- rlist =[sys.stdin, s]
- read_list, write_list, error_list =select.select(rlist,[],[])
- for sock in read_list:
- if sock == s:
- data = sock.recv(2048)
- ifnot data:
- continue
- else:
- sys.stdout.write(data)
- else:
- msg = raw_input("我说: ")
- s.sendall(msg)
来源: http://www.bubuko.com/infodetail-2451676.html