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,如需转载请自行联系原作者

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • TCP-RST_tcp快速重传为什么是三次

    TCP-RST_tcp快速重传为什么是三次        在谈RST攻击前,必须先了解TCP:如何通过三次握手建立TCP连接、四次握手怎样把全双工的连接关闭掉、滑动窗口是怎么传输数据的、TCP的flag标志位里RST在哪些情况下出现。下面我会画一些尽量简化的图来表达清楚上述几点,之后再了解下RST攻击是怎么回事。1、TCP是什么?TCP是在IP网络层之上的传输层协议,用于提供port到port面向连接的可靠…

    2022年10月1日
    0
  • Python字符串使用详解

    Python字符串使用详解除了数字,Python中最常见的数据类型就是字符串,无论那种编程语言,字符串无处不在。例如,从用户哪里读取字符串,并将字符串打印到屏幕显示出来。字符串是一种数据结构,这让我们有机会学习索引和切片——用于从字符串中提取子串的方法。1字符串索引在Python语法支持中,我们简单的阐述过字符串的使用,现在我们看看python程序在处理字符串时,如何对其进行索引,打印出其中的每个字符串。我们输入一个字符串:’你好,Lucky’,Python使用方括号[]来对字符串进行索引,方括号内的数字0~n表

    2022年10月25日
    0
  • python打包exe的方法

    cxfreeze,pyinstaller,py2exe三种方式cxfreeze最简单,安装后脚本在python_home\Scripts下面执行pythoncxfreeze全路径要打包的py文件 –target-dir

    2022年4月8日
    25
  • pytest的assert_assert断言语句

    pytest的assert_assert断言语句前言断言是写自动化测试基本最重要的一步,一个用例没有断言,就失去了自动化测试的意义了。什么是断言呢?简单来讲就是实际结果和期望结果去对比,符合预期那就测试pass,不符合预期那就测试failed

    2022年7月28日
    3
  • pycharm调试python_pycharm调试快捷键

    pycharm调试python_pycharm调试快捷键最全设置资料,请见:http://www.cnblogs.com/tsingke/p/7392800.htmlPyCharm简介:PyCharm是由JetBrains打造的一款PythonIDE,VS2010的重构插件Resharper就是出自JetBrains之手。同时支持GoogleAppEngine,PyCharm支持IronPython。这些功能在先进代码分…

    2022年8月27日
    3
  • 学习Java有什么用 可以从事哪些工作

    学习Java有什么用 可以从事哪些工作Java开发应用广泛,是目前互联网行业不可缺少的语言,因此越来越多的人选择学习Java。对于初学者而言,学完Java除了可以从事Java开发之外,还可以做哪些具体的工作岗位呢?一、Android应用 Android是一种基于Linux的自由及开放源代码的操作系统,其源代码是Java。目前企业级特别大的应用,都需要学Java。而Java做安卓开发不单单是指系统,还有APP,在Andro…

    2022年7月7日
    26

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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