python之epoll服务器源码分析
#!/usr/bin/env python
# -*- coding: utf8 -*- import socket, select EOL1 = b'/r/n'
EOL2 = b'/r/n/r/n' # 拼接成的response
response = b'HTTP/1.0 200 OK/r/nDate: Mon, 1 Jan 1996 01:01:01 GMT/r/n'
response += b'Content-Type: text/plain/r/nContent-Length: 13/r/n/r/n'
response += b'Hello, world!' # 创建一个服务端的socket,来监听是否有请求过来
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, )
serversocket.bind(('0.0.0.0', )) # 绑定
serversocket.listen() # 监听
serversocket.setblocking() # 设置时非阻塞
print(serversocket.fileno())
epoll = select.epoll() # 准备设计一个IO多路复用
epoll.register(serversocket.fileno(), select.EPOLLIN) # 把上面的serversocket的fileno() 和 监听准备读信号 注册到epoll中去 try:
# 设置三个空字典
connections = {}
requests = {}
responses = {}
while True:
# 查看epoll是否有信号有的话,就放在events中
events = epoll.poll() # 循环events,分别拿到 文件描述号 和对应的事件
for fileno, event in events:
# 如果当前的文件描述号是serversocket,那么说明有新的连接
if fileno == serversocket.fileno():
# 所以就得接受,创建了 连接,拿到了对方的IP地址
connection, address = serversocket.accept()
# connection就是客户端连接过来建立的socket,设置为非阻塞
connection.setblocking()
# 客户端建立的socket也注册到select模块的IO多路复用中去
epoll.register(connection.fileno(), select.EPOLLIN) # 以Connection的文件描述号 作为键 socket作为值保存在connections中
connections[connection.fileno()] = connection # 同时在requests和responses字典中,
# requests中 以connection.fileno() 作为键 以请求的内容作为值
# responses中 以connection.fileno() 作为键 以相应的内容作为值,这个我们返回的是固定的,仅仅返回hello world requests[connection.fileno()] = b''
responses[connection.fileno()] = response # 如果请求的数据不是socketserver,那肯定是客户端的,判断是否是准备读的信号
elif event & select.EPOLLIN:
# 立马来开始读取数据,加到requests对象套接字的内容中去
requests[fileno] += connections[fileno].recv() # 判断换行 和 两个换行是否在接收过来的数据中
if EOL1 in requests[fileno] or EOL2 in requests[fileno]:
# 如果是的话,就将这个套接字的监听更新为准备写
epoll.modify(fileno, select.EPOLLOUT) # 打印40个-,然后换行,加上请求的内容
print('-' * + '/n' + requests[fileno].decode()[:-])
# 如果请求的数据不是socketserver,那肯定是客户端的,判断是否是准备写的信号
elif event & select.EPOLLOUT:
# 立马来开始读取数据,就将response的对应的套接字号对应的值拿出来,其实就是hello world,O(∩_∩)O哈哈~
# 并统计发送了多少个字节
byteswritten = connections[fileno].send(responses[fileno])
# 更新response对应套接字内容为剩下的内容
responses[fileno] = responses[fileno][byteswritten:]
# 如果内容发完了,剩下的长度就是0,如果长度是0
if len(responses[fileno]) == :
# 就修改select,不监听该套接字的内容,其就变成了EPOLLHUP
epoll.modify(fileno, )
# 然后关闭该socket的管道
connections[fileno].shutdown(socket.SHUT_RDWR)
elif event & select.EPOLLHUP:
# 如果不监听该套接字的内容,就将其注销掉
epoll.unregister(fileno)
# 关闭该套接字
connections[fileno].close()
# 从连接中删除该文件描述符
del connections[fileno]
finally:
# 最后关闭serversocket服务器套接字
epoll.unregister(serversocket.fileno())
# 关闭epoll
epoll.close()
# 套接字关闭
serversocket.close()
python之epoll服务器源码分析的更多相关文章
- epoll(2) 源码分析
epoll(2) 源码分析 文本内核代码取自 5.0.18 版本,和上一篇文章中的版本不同是因为另一个电脑出了问题,但是总体差异不大. 引子留下的问题 关键数据结构 提供的系统调用 就绪事件相关逻辑 ...
- tiny web服务器源码分析
tiny web服务器源码分析 正如csapp书中所记,在短短250行代码中,它结合了许多我们已经学习到的思想,如进程控制,unix I/O,套接字接口和HTTP.虽然它缺乏一个实际服务器所具备的功能 ...
- [1]传奇3服务器源码分析一 LoginGate
服务端下载地址: 点击这里 网上基本上都有分析该源码的分析详解,如:请点击该链接,但容易晕,而且也不全!所以才有了本文! 一.首先来看服务端的LoginGate源码 先来张图比较让人容易理解
- trinitycore 魔兽服务器源码分析(三) 多线程相关
先看LockedQueue.h template <class T, typename StorageType = std::deque<T> >class LockedQue ...
- Python线程池ThreadPoolExecutor源码分析
在学习concurrent库时遇到了一些问题,后来搞清楚了,这里记录一下 先看个例子: import time from concurrent.futures import ThreadPoolExe ...
- trinitycore 魔兽服务器源码分析(二) 网络
书接上文 继续分析Socket.h SocketMgr.h template<class T>class Socket : public std::enable_shared_from_t ...
- epoll内核源码分析
转载:https://www.nowcoder.com/discuss/26226?type=0&order=0&pos=27&page=1 /* * fs/eventpo ...
- trinitycore 魔兽服务器源码分析(一) 网络
trinitycore是游戏服务器的开源代码 许多玩家使用魔兽的数据来进行测试 ,使用它来假设魔兽私服. 官方网址 https://www.trinitycore.org/ 类似的还有mangos ...
- 基于python的ardrone control源码分析与心得
这里有一段python代码,可用于操控ardrone 2.0.实验室曾经借鉴用过,并添加了部分功能.如今复习一下,顺便理理python的相关知识点. #!/usr/bin/env python # A ...
随机推荐
- 并发容器ConcurrentHashMap与synchronized联合使用达到线程安全
http://blog.csdn.net/yansong_8686/article/details/50664338 map.put(KEY, map.get(KEY) + 1); 实际上并不是原子操 ...
- NativeScriptEngineService 被调用流程
AbsractSearchScritp 有个lookup! NativeScriptEngineService search()会调用 script.setLookup() NativeScriptE ...
- 手机端调试console.log,直接引入一个js文件
http://files.cnblogs.com/files/lwwen/mConsole.js 这是我写的一个原生js文件 直接引入即可,可以把html上面的需要打印的东西打印出来 <!DOC ...
- MapReduce案例一:天气温度
1.需求 2.思路 3.代码实现 3.1MyWeather 类代码: 这个类主要是用来定义hadoop的配置,在执行计算程序时所需加载的一些类. package com.hadoop.mr.weath ...
- hdu 1226(同余搜索)
超级密码 Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- hdu 2686&&hdu 3376(拆点+构图+最小费用最大流)
Matrix Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- hdu 4198:Quick out of the Harbour解题报告
Quick out of the Harbour Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java ...
- (翻译)Xamarin.Essentials: 移动应用的跨平台 API
原文地址:https://blog.xamarin.com/xamarin-essentials-cross-platform-apis-mobile-apps/ 当使用 Xamarin 开发 IOS ...
- nginx 开启 gzip
gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_comp_level 2; gzip_types text/plain applicatio ...
- nginx的http负载均衡
注意:nginx自带的http服务后端检测有缺陷,无法根据状态码来检测,建议使用tengine的nginx_upstream_check_module来实现后端服务的http健康状态检测 (1)负载均 ...