基于python的聊天室_Python实现web聊天室

使用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端代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57#/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 rin 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 iin self.socketList:

if i != rand 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端代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31#/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 sockin 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)

本文转自 粗粮面包 51CTO博客,原文链接:http://blog.51cto.com/culiangmianbao/2058054,如需转载请自行联系原作者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值