web服务-3、epoll高效率实现并发服务器
知识点:
之前写的四种方法实现并发服务效率都还是低,早期的服务器采用的是select和poll方式,select这种方式的特点是轮询所有套接字去一个个看有没有事件发生,但是装套接字的列表长度是有限制的,而且轮询方式效率低,poll方式只是解决了装套接字这个列表的长度限制,但也是采用轮询的方式。目前实际场景中,linux服务器采用的都是epoll方案实现并发服务的,它解决了轮询这种低效率方式,采用事件通知的方式告诉应用程序哪个套接字发来了数据它的效率远远高于其他四种,它也是采用单进程单线程的方式,但是是堵塞的,主要有俩大特点:1、epoll方式会映射一个和操作系统一样的能处理应用程序的指定的文件描述符内存空间(即省去了将应用程序中的套接字文件描述符拷贝到操作系统中的过程),它既不属于应用程序也不属于操作系统 ,是俩个共用的的2、客户端套接字发送数据,epoll采用事件通知方式告诉应用程序,而不需要轮询所有的套接字列表
1、代码实现:
#!/usr/bin/env python
# coding=utf-8
# author:刘仲
# datetime:2018/8/6 9:24
# software: PyCharm import socket
import select
import re
"""之前写的四种方法实现并发服务效率都还是低,早期的服务器采用的是select和poll方式,select这种方式的特点是轮询所有套接字去
一个个看有没有事件发生,但是装套接字的列表是有限制的,而且轮询方式效率低,poll方式只是解决了装套接字这个列表的长度限制,
但也是采用轮询的方式。目前实际场景中,linux服务器采用的都是epoll方案实现并发服务的,它解决了轮询这种低效率方式,采用事件
通知的方式告诉应用程序哪个套接字发来了数据它的效率远远高于其他四种,它也是采用单进程单线程的方式,但是是堵塞的,主要有俩
大特点:1、epoll方式会映射一个和内核一样的能处理应用程序的事件的2、客户端套接字发送数据,内核的文件系统会采用事件通知的
方式告诉应用程序
""" def webserver():
web_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
web_socket.bind(('127.0.0.1', 7786))
web_socket.listen(128)
epl = select.epoll() # 创建epoll对象
epl.register(web_socket.fileno(), select.EPOLLIN | select.EPOLLET) # 将监听套接字注册到epl
fd_dict = dict() # 存放新的套接字的文件描述符和与之对应的套接字对象
while True:
epl_list = epl.poll() # 默认堵塞,获取注册到epl对象中的所有套接字列表,列表里存的是元祖,元祖俩个值分别对应的是
# 套接字的文件描述符和事件类型
for fd, event in epl_list: # 获取套接字的文件描述符和事件类型
if fd == web_socket.fileno(): # 刚开始epl_list肯定存放的是监听套接字,所以新的客户端链接进来,先判断文件描述符是否等与监听套接字的文件描述符 new_socket, new_adress = web_socket.accept() # 新客户端链接进来进行解堵塞
fd_dict[new_socket.fileno()] = new_socket # 将新的客户端套接字的文件描述符和与之对应的套接字存放到字典中
epl.register(new_socket.fileno(), select.EPOLLIN) # 将新的套接字注册到epl中
elif event == select.EPOLLIN: # 当监听事件触发,即客户端发来数据
try:
data = fd_dict[fd].recv(1024).decode('utf-8')
except:
print('客户端没有发送数据')
else:
if data:
data1 = data.splitlines()
request_url = re.match(r"[^/]+(/[^ ]*)",data1[0])
if request_url:
file_name = request_url.group(1)
if file_name == '/': file_name = '/index.html'
try:
body = open('./html'+file_name, 'rb')
except:
response_head = 'HTTP 404 NOT FOUND/1.1\r\n'
response_head += '\r\n'
response_body = '<h1>NOT FOUND PAGE</H1>'
fd_dict[fd].send((response_head + response_body).encode('utf-8'))
else:
response_body = body.read()
body.close()
response_head = 'HTTP 200 OK/1.1\r\n'
response_head += 'Content-Length:%d\r\n'%len(response_body)
response_head += '\r\n'
fd_dict[fd].send(response_head.encode('utf-8')+response_body)
fd_dict[fd].close() else: fd_dict[fd].close() # 关闭新的套接字
epl.unregister(fd) # 从epl中移除该文件描述符的链接
del fd_dict[fd] # 删除这个套接字的键值对
web_socket.close() if __name__ == '__main__':
webserver()
web服务-3、epoll高效率实现并发服务器的更多相关文章
- Linux + C + Epoll实现高并发服务器(线程池 + 数据库连接池)(转)
转自:http://blog.csdn.net/wuyuxing24/article/details/48758927 一, 背景 先说下我要实现的功能,server端一直在linux平台下面跑,当客 ...
- 基于线程池、消息队列和epoll模型实现并发服务器架构
引言 并发是什么?企业在进行产品开发过程中为什么需要考虑这个问题?想象一下天猫的双11和京东的618活动,一秒的点击量就有几十万甚至上百万,这么多请求一下子涌入到服务器,服务器需要对这么多的请求逐个进 ...
- Angular内提供了一个可以快速建立测试用web服务的方法:内存 (in-memory) 服务器
如何使用 Angular 内存 (in-memory) 服务器https://segmentfault.com/a/1190000009898540
- nginx web服务优化
nginx基本安全优化 1. 调整参数隐藏nginx软件版本号信息 软件的漏洞和版本有关,我们应尽量隐藏或消除web服务对访问用户显示各类敏感信息(例如web软件名称及版本号等信息),这样恶意的用户就 ...
- linux web服务基础知识,dns
#web服务基础知识c/s 客户端/服务器b/s 浏览器/服务器 nginx > web server 服务端浏览器 > web client 客户端 #dns解析 ...
- golang 简单web服务
1.golang print输入 package main import "fmt" func main() { fmt.Printf("Hello World!\n&q ...
- LINUX环境并发服务器的三种实现模型
服务器设计技术有很多,按使用的协议来分有TCP服务器和UDP服务器.按处理方式来分有循环服务器和并发服务器. 1 循环服务器与并发服务器模型 在网络程序里面,一般来说都是许多客户对应一个服务器,为了 ...
- 如何读懂Web服务的系统架构图
Web服务的一个重要特点就是流量大.数据多,仅靠一台服务器肯定难以支撑大规模的服务. 所以我们经常会看到诸如以下的一些术语,教人好生不懂: *:系统架构.物理架构.Web服务基础设施 *:应用服务器 ...
- web服务-2、四种方法实现并发服务器-多线程,多进程,协程,(单进程-单线程-非堵塞)
知识点:1.使用多线程,多进程,协程完成web并发服务器 2.单进程-单线程-非堵塞也可以实现并发服务器 1.多进程和协程的代码在下面注释掉的部分,我把三种写在一起了 import socket im ...
随机推荐
- Django Cookie,Session
Cookie Cookie的由来 HTTP协议是无状态的,每次请求都是独立的,对服务器来说,每次的请求都是全新的,上一次的访问是数 据是无法保留到下一次的 某些场景需要状态数据或者中间数据等相关对下一 ...
- java String转int int转化为String
String转int String str = "123"; int a = Integer.parseInt(str); System.out.println(a); Integ ...
- java远程文件操作
有时在项目中,会有专门的文件服务器(windows),这个时候我们需要对文件进行操作时,就不能像操作本地文件那样操作文件服务器的文件.这时候就可以用SmbFile来操作了. 首先添加jar包,mave ...
- B-树(B树)详解
具体讲解之前,有一点,再次强调下:B-树,即为B树.因为B树的原英文名称为B-tree,而国内很多人喜欢把B-tree译作B-树,其实,这是个非常不好的直译,很容易让人产生误解.如人们可能会以为B-树 ...
- busybox(四)完善
目录 busybox(四)完善 proc挂载 手动挂载 proc解析 使用脚本自动挂载 使用mount-a挂载 udev/mdev 挂载 使用jffs2 文件系统格式 安装zlib 安装jffs2 生 ...
- 如何在IntelliJ IDEA中使用.ignore插件忽略不必要提交的文件
如何在IntelliJ IDEA中使用.ignore插件忽略不必要提交的文件 最近初学Git,而且在使用的IDE是IntelliJ IDEA,发现IDEA在提交项目到本地仓库的时候,会把.idea文件 ...
- 浏览器录宏重放软件-iMacros
iMacros https://imacros.net/ iMacros v12 Now Available The world's most popular web automation, data ...
- 爬取qq音乐巅峰榜---内地音乐的榜单
import requestsimport jsonimport sys for i in range(0,10): url = "https://szc.y.qq.com/v8/fcg-b ...
- MySQL的一些基本命令笔记(3)
指明外键: 1 :1 两个表中的主键都可以当成外键 1 :N 在 "多" 的实体表中新增加一个字段,该字段是 "一" 实体表的主键 M : N 拆成两个1 :N ...
- mysql中使用enum,如何获取所有可能的值
SELECT column_type FROM information_schema. COLUMNS WHERE TABLE_SCHEMA = "数据库名" AND DATA_T ...