知识点:

    之前写的四种方法实现并发服务效率都还是低,早期的服务器采用的是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高效率实现并发服务器的更多相关文章

  1. Linux + C + Epoll实现高并发服务器(线程池 + 数据库连接池)(转)

    转自:http://blog.csdn.net/wuyuxing24/article/details/48758927 一, 背景 先说下我要实现的功能,server端一直在linux平台下面跑,当客 ...

  2. 基于线程池、消息队列和epoll模型实现并发服务器架构

    引言 并发是什么?企业在进行产品开发过程中为什么需要考虑这个问题?想象一下天猫的双11和京东的618活动,一秒的点击量就有几十万甚至上百万,这么多请求一下子涌入到服务器,服务器需要对这么多的请求逐个进 ...

  3. Angular内提供了一个可以快速建立测试用web服务的方法:内存 (in-memory) 服务器

    如何使用 Angular 内存 (in-memory) 服务器https://segmentfault.com/a/1190000009898540

  4. nginx web服务优化

    nginx基本安全优化 1. 调整参数隐藏nginx软件版本号信息 软件的漏洞和版本有关,我们应尽量隐藏或消除web服务对访问用户显示各类敏感信息(例如web软件名称及版本号等信息),这样恶意的用户就 ...

  5. linux web服务基础知识,dns

    #web服务基础知识c/s 客户端/服务器b/s 浏览器/服务器 nginx   >   web  server  服务端浏览器  >    web  client  客户端 #dns解析 ...

  6. golang 简单web服务

    1.golang print输入 package main import "fmt" func main() { fmt.Printf("Hello World!\n&q ...

  7. LINUX环境并发服务器的三种实现模型

    服务器设计技术有很多,按使用的协议来分有TCP服务器和UDP服务器.按处理方式来分有循环服务器和并发服务器. 1  循环服务器与并发服务器模型 在网络程序里面,一般来说都是许多客户对应一个服务器,为了 ...

  8. 如何读懂Web服务的系统架构图

    Web服务的一个重要特点就是流量大.数据多,仅靠一台服务器肯定难以支撑大规模的服务. 所以我们经常会看到诸如以下的一些术语,教人好生不懂: *:系统架构.物理架构.Web服务基础设施 *:应用服务器 ...

  9. web服务-2、四种方法实现并发服务器-多线程,多进程,协程,(单进程-单线程-非堵塞)

    知识点:1.使用多线程,多进程,协程完成web并发服务器 2.单进程-单线程-非堵塞也可以实现并发服务器 1.多进程和协程的代码在下面注释掉的部分,我把三种写在一起了 import socket im ...

随机推荐

  1. django restframework 跨域访问

    场景介绍: 在Django开发过程中,使用前后端分离设计的站点越来越多,如Django+VUE.Django+Angular.在使用DjangoRestFramework开发API的过程中,由于前端站 ...

  2. Kafka遇到30042ms has passed since batch creation plus linger time at org.apache.kafka.clients.producer.internals.FutureRecordMetadata.valueOrError(FutureRecordMetadata.java:94)

    问题描述: 运行生产者线程的时候显示如下错误信息: Expiring 1 record(s) for XXX-0: 30042 ms has passed since batch creation p ...

  3. 关于confluence上传文件附件预览查看时出现乱码的问题解决办法

    在confluence上传excel文件,预览时发现乱码问题主要是因为再上传文件的时候一般是Windows下的文件上传,而预览的时候,是linux下的环境,由于linux下没有微软字体,所以预览的时候 ...

  4. crm 数据展示 和分页思想(一)

    1. 数据的展示 数据通过ORM查询出来 对象列表 QuerySet 1. 普通的字段 对象.字段名 ——> 数据库中的值 <td>{{ customer.phone }}</ ...

  5. 静态IP设置

    先查看自动网络的ip地址,然后设置 cmd进入DOS输入命令:ipconfig /all 设置固定IP

  6. BeautifulSoup解析模块

    简介: Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式. 使用 from bs4 impor ...

  7. DirectX11 With Windows SDK--17 利用几何着色器实现公告板效果

    前言 上一章我们知道了如何使用几何着色器将顶点通过流输出阶段输出到绑定的顶点缓冲区.接下来我们继续利用它来实现一些新的效果,在这一章,你将了解: 实现公告板效果 Alpha-To-Coverage 对 ...

  8. 第十二节:MVC中的一些特殊优化

    一. 删除WebForm视图引擎 在MVC框架中检索视图的顺序为:当前控制器下对应的文件夹的aspx文件→share文件夹aspx文件→当前控制器下对应文件夹的cshtml文件→share文件夹的cs ...

  9. 闭包创建自己的 plugin 示例 加载 loading

    plugin  插件 什么是 plugin? 实现一个功能,与主应用程序分离,减少主应用程序的大小,高复用,可维护 制作过程中,一定要避免依赖其他的元素,减少 id 等的使用,避免与页面中其他内容冲突 ...

  10. Node.js实战项目学习系列(2) 开发环境和调试工具

    前言 上一节让我们对Node.js有一个初步的了解,那么现在可以开始正式学习下Node.js的开发了,但是任何一门语言要设计到开发,就必须先学习开发环境以及调试.本文将主要讲解这些内容. 本文涉及到的 ...