Python实现web聊天室「建议收藏」

Python实现web聊天室「建议收藏」使用Python模块中的select模块实现web聊天室功能select模块Python中的select模块专注于I/O多路复用,提供了selectpollepoll三个方法(其中后两个在Linux中可用,windows仅支持select),另外也提供了kqueue方法(freeBSD系统)参数:可接受四个参数(前三个必须)r…

大家好,又见面了,我是你们的朋友全栈君。

使用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 

in 
rlist:
                
if 

=
= 
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 

in 
self
.socketList:
            
if 
i !
= 

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

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
    

= 
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)



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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/152175.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号