Python實現web聊天室
阿新 • • 發佈:2018-01-06
支持 put all rem message one utf cti 訪問 使用Python模塊中的select模塊實現web聊天室功能 某一個函數或者動作成功完成後,會自動觸發一個函數為所有的fd綁定一個回調函數,一旦有數據訪問,觸發改回調函數,回調函數把fd放到鏈表中。(只要有活動,把fd放到鏈表中,動態監聽)這樣就提高了效率。例子:交試卷
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拷貝到內核空間,只需要拷貝一次
第二個函數: 回調函數
第三個函數,判斷鏈表是否為空
server端代碼
#/usr/bin/env python #-*- coding:utf-8 -*- import socket import select # 封裝 class SelectServer(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!") while 1: 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)) except Exception as 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 in self.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端代碼
#/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') while 1: 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) if not data: continue else: sys.stdout.write(data) else: msg = raw_input("我說: ") s.sendall(msg)
Python實現web聊天室