问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何实现一个非阻塞的socket

发布网友 发布时间:2022-04-18 17:21

我来回答

2个回答

懂视网 时间:2022-04-18 21:42

本篇将使用200行代码完成一个微型异步非阻塞Web框架:Snow。具有很好的参考价值,下面跟着小编一起来看下吧

Python的Web框架中Tornado以异步非阻塞而闻名。本篇将使用200行代码完成一个微型异步非阻塞Web框架:Snow。

一、源码

本文基于非阻塞的Socket以及IO多路复用从而实现异步非阻塞的Web框架,其中便是众多异步非阻塞Web框架内部原理。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
import socket
import select
import time
class HttpResponse(object):
 """
 封装响应信息
 """
 def init(self, content=''):
 self.content = content
 self.headers = {}
 self.cookies = {}
 def response(self):
 return bytes(self.content, encoding='utf-8')
class HttpNotFound(HttpResponse):
 """
 404时的错误提示
 """
 def init(self):
 super(HttpNotFound, self).init('404 Not Found')
class HttpRequest(object):
 """
 用户封装用户请求信息
 """
 def init(self, conn):
 self.conn = conn
 self.header_bytes = bytes()
 self.header_dict = {}
 self.body_bytes = bytes()
 self.method = ""
 self.url = ""
 self.protocol = ""
 self.initialize()
 self.initialize_headers()
 def initialize(self):
 header_flag = False
 while True:
 try:
 received = self.conn.recv(8096)
 except Exception as e:
 received = None
 if not received:
 break
 if header_flag:
 self.body_bytes += received
 continue
 temp = received.split(b'

', 1)
 if len(temp) == 1:
 self.header_bytes += temp
 else:
 h, b = temp
 self.header_bytes += h
 self.body_bytes += b
 header_flag = True
 @property
 def header_str(self):
 return str(self.header_bytes, encoding='utf-8')
 def initialize_headers(self):
 headers = self.header_str.split('
')
 first_line = headers[0].split(' ')
 if len(first_line) == 3:
 self.method, self.url, self.protocol = headers[0].split(' ')
 for line in headers:
 kv = line.split(':')
 if len(kv) == 2:
 k, v = kv
 self.header_dict[k] = v
class Future(object):
 """
 异步非阻塞模式时封装回调函数以及是否准备就绪
 """
 def init(self, callback):
 self.callback = callback
 self._ready = False
 self.value = None
 def set_result(self, value=None):
 self.value = value
 self._ready = True
 @property
 def ready(self):
 return self._ready
class TimeoutFuture(Future):
 """
 异步非阻塞超时
 """
 def init(self, timeout):
 super(TimeoutFuture, self).init(callback=None)
 self.timeout = timeout
 self.start_time = time.time()
 @property
 def ready(self):
 current_time = time.time()
 if current_time > self.start_time + self.timeout:
 self._ready = True
 return self._ready
class Snow(object):
 """
 微型Web框架类
 """
 def init(self, routes):
 self.routes = routes
 self.inputs = set()
 self.request = None
 self.async_request_handler = {}
 def run(self, host='localhost', port=9999):
 """
 事件循环
 :param host:
 :param port:
 :return:
 """
 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 sock.bind((host, port,))
 sock.setblocking(False)
 sock.listen(128)
 sock.setblocking(0)
 self.inputs.add(sock)
 try:
 while True:
 readable_list, writeable_list, error_list = select.select(self.inputs, [], self.inputs,0.005)
 for conn in readable_list:
 if sock == conn:
 client, address = conn.accept()
 client.setblocking(False)
 self.inputs.add(client)
 else:
 gen = self.process(conn)
 if isinstance(gen, HttpResponse):
 conn.sendall(gen.response())
 self.inputs.remove(conn)
 conn.close()
 else:
 yielded = next(gen)
self.async_request_handler[conn] = yielded
 self.polling_callback()
except Exception as e:
 pass
 finally:
 sock.close()
def polling_callback(self):
 """
 遍历触发异步非阻塞的回调函数
 :return:
 """
 for conn in list(self.async_request_handler.keys()):
 yielded = self.async_request_handler[conn]
 if not yielded.ready:
 continue
 if yielded.callback:
 ret = yielded.callback(self.request, yielded)
 conn.sendall(ret.response())
 self.inputs.remove(conn)
 del self.async_request_handler[conn]
 conn.close()
 def process(self, conn):
 """
 处理路由系统以及执行函数
 :param conn:
 :return:
 """
 self.request = HttpRequest(conn)
 func = None
 for route in self.routes:
 if re.match(route[0], self.request.url):
 func = route[1]
 break
 if not func:
 return HttpNotFound()
 else:
 return func(self.request)
snow.py

二、使用

1. 基本使用

from snow import Snow
from snow import HttpResponse
def index(request):
return HttpResponse('OK')
routes = [
 (r'/index/', index),
]
app = Snow(routes)
app.run(port=8012)

2.异步非阻塞:超时

from snow import Snow
from snow import HttpResponse
from snow import TimeoutFuture
request_list = []
def async(request):
 obj = TimeoutFuture(5)
 yield obj
def home(request):
 return HttpResponse('home')
routes = [
 (r'/home/', home),
 (r'/async/', async),
]
app = Snow(routes)
app.run(port=8012)

3.异步非阻塞:等待

基于等待模式可以完成自定制操作

from snow import Snow
from snow import HttpResponse
from snow import Future
request_list = []
def callback(request, future):
 return HttpResponse(future.value)
def req(request):
 obj = Future(callback=callback)
 request_list.append(obj)
 yield obj
def stop(request):
 obj = request_list[0]
 del request_list[0]
 obj.set_result('done')
 return HttpResponse('stop')
routes = [
 (r'/req/', req),
 (r'/stop/', stop),
]
app = Snow(routes)
app.run(port=8012)

【相关推荐】

1. Python免费视频教程

2. Python学习手册

3. Python面向对象视频教程

热心网友 时间:2022-04-18 18:50

所谓非阻塞模式就是,当主线程做一个操作的时候不会阻塞,而是可以继续往下执行别的代码。比如说如果你主线程用socket发送一段数据,这是需要一定的时间的,这个时候你的主线程就被阻塞了,必须等发送完了才能执行其它的代码。而假如你把这个发送的操作交给另外的一个线程去做,那么主线程就可以继续干别的了。所以说在要想做到非阻塞,基本上就是用多线程去实现了
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
福如东海终身寿险(A款)(分红型)能退多少钱 我买的新华人寿保险福如东海A型,但是想退了。 杭州樱花日语学校的学习效果如何得到管理与跟踪? 枣子不能与什么一起吃 枣子和什么食物相克 枣子和什么相克 枣子跟什么不能一起吃 电风扇带不动风叶拿掉风叶能转是怎么回事 嵌入式学习首先要学什么基础 学习嵌入式的基础是什么 爱奇艺人工服务电话为什么就是个摆设,打了一个星期了,办了包年会员,结果到现在都不是会员,坑爹啊,垃 在淘宝上怎么直播视频 饮水机热水口不出水 bluepro饮水机不出热水? 4.socket框架netty的使用,以及nio的实现原理,为什么是异步非阻塞 二硫化钼润滑脂的性能特点是什么? 梦到拆迁 黑绒鞋发白怎么办 建行快贷当前逾期还款后,下个月能申请到账吗? 中国以战争方式参与朝鲜战争说明了什么? 美帝国主义侵略的是朝鲜又不是中国,我中国志愿军为什么还要去奔赴朝鲜参与抗击美国侵略者? 抗美援朝中国为何参战 如何快速的包饺子的做法 飞机在空中怎样控制方向转弯啊? 飞机转弯是通过怎样一个原理的 劳动法关于离职交接规定 为什么飞机转弯要倾斜机身? 请问一下飞机在空中和地面的转弯系统是什么?谢谢 飞机靠什么转弯 飞机在空中和地面上时,各自是靠什么来完成转弯动作的呢,这可没有汽车的传动轴啊. 怎么做止咳的食物,用水果类来做? 问个问题,请大神回答下.标书可以用微信或者支付宝吗 简述羽毛球双打的指导思想是什么? 求羽毛球双打训练指导 中位数要怎么算? 羽毛球双打比赛的指导思想 急!怀孕4个月肚子疼! 安全生产青年当先 我心雀跃的作文怎么写??? 我心雀跃作文怎么写800 我心雀跃作文开头怎么写 我心雀跃有什么事情可写 我心雀跃作文开头结尾怎样写 作文《我心雀跃》开头? 我心雀跃可以下载吗 你能理解“我心雀跃”这篇文章的最后一段话吗? 我心雀跃美术老师和生物老师是一家么 我心雀跃(写作) 急求一篇《在我雀跃的时刻》作文, 写一件事,条理通顺,不少于450字!急急急急急!! 忍不住欢呼雀跃作文 全世界唯一没有肚脐的超模,卡罗莱娜.科库娃为何会成为维密宠儿?