简单的Web Server

import socket

eol1 = b'\n\n'
eol2 = b'\n\r\n'
body = '''Hello,world!<h1>tszrwyx</h1>'''
response_params = ['HTTP/1.0 200OK',
'Date:Sun,27 may 2018 01:01:01 GMT',
'Content-Type:text/plain;charset=utf-8',
'Content-Length:{}\r\n.format(len(body.encode()))',
body]
response = '\r\n'.join(response_params) def handle_connection(conn, addr):
print('oh,new conn',conn,addr)
import time
time.sleep(100)
request = b''
while((eol1 not in request)and(eol2 not in request)):
request += conn.recv(1024)
print(request)
conn.send(response.encode()) #response转为bytes后传输
conn.close() def main():
#socket.AF_INET用于服务器与服务器之间的网络通信
#socket.SOCK_STREAM用于基于TCP的流式socket通信
serversocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#设置端口可复用,保证我们每次按Ctrl+C组合键之后,快速重启
serversocket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
serversocket.bind(('127.0.0.1',8000))
serversocket.listen(5)#设置backlog-socket连接最大排队数量
print('http://127.0.0.1:8000')
try:
while(True):
conn,address = serversocket.accept()
handle_connection(conn,address)
finally:
serversocket.close() if __name__=='__main__':
main()

多线程版的WEB SERVER

# coding:utf-8

import time
import errno
import socket
import threading EOL1 = b'\n\n'
EOL2 = b'\n\r\n'
body = '''Hello, world! <h1> from the5fire</h1> - from {thread_name}''' response_params = [
'HTTP/1.0 200 OK',
'Date: Sun, 27 may 2018 01:01:01 GMT',
'Content-Type: text/plain; charset=utf-8',
'Content-Length: {length}\r\n',
body,
]
response = '\r\n'.join(response_params) def handle_connection(conn, addr):
print(conn, addr)
# time.sleep(60)
request = b""
while EOL1 not in request and EOL2 not in request:
request += conn.recv(1024)
print(request)
current_thread = threading.currentThread()
content_length = len(body.format(thread_name=current_thread.name).encode())
print(current_thread.name)
conn.send(response.format(thread_name=current_thread.name, length=content_length).encode())
conn.close() def main():
# socket.AF_INET 用于服务器与服务器之间的网络通信
# socket.SOCK_STREAM 基于TCP的流式socket通信
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置端口可复用,保证我们每次Ctrl C之后,快速再次重启
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversocket.bind(('127.0.0.1', 8000))
# 可参考:https://stackoverflow.com/questions/2444459/python-sock-listen
serversocket.listen(10)
print('http://127.0.0.1:8000')
serversocket.setblocking(1) # 设置socket为非阻塞模式 try:
i = 0
while True:
try:
conn, address = serversocket.accept()
except socket.error as e:
if e.args[0] != errno.EAGAIN:
raise
continue
i += 1
print(i)
t = threading.Thread(target=handle_connection, args=(conn, address), name='thread-%s' % i)
t.start()
finally:
serversocket.close() if __name__ == '__main__':
main()

简单的WSGI application

WSGI协议分为两部分,其中一部分是Web Server或者Gateway,就像上面的代码一样,监听在某个端口上,接受外部的请求。另外一部分是Web Application,Web Server接受到请求之后会通过WSGI协议规定的方式把数据传递给Web Application,我们在Web Application中处理完之后,设置对应的状态和HEADER,之后返回body部分。Web Server拿到返回数据之后,再进行HTTP协议的封装,最终返回完整的HTTP Response数据。

# coding:utf-8

#这就是一个简单的application
def simple_app(environ, start_response):
status = '200 OK'
response_headers = [('Content-type', 'text/plain')]
start_response(status, response_headers)
return ['Hello world! -by the5fire \n']
# coding:utf-8

#运行application
import os
import sys def run_with_cgi(application):
environ = dict(os.environ.items())
environ['wsgi.input'] = sys.stdin
environ['wsgi.errors'] = sys.stderr
environ['wsgi.version'] = (1, 0)
environ['wsgi.multithread'] = False
environ['wsgi.multiprocess'] = True
environ['wsgi.run_once'] = True if environ.get('HTTPS', 'off') in ('on', ''):
environ['wsgi.url_scheme'] = 'https'
else:
environ['wsgi.url_scheme'] = 'http' headers_set = []
headers_sent = []
def write(data):
#如果headers_set是空的话就抛出下面这个异常
if not headers_set:
raise AssertionError("write() before start_response()")
elif not headers_sent:
# Before the first output, send the stored headers
status, response_headers = headers_sent[:] = headers_set
sys.stdout.write('Status: %s\r\n' % status)
for header in response_headers:
sys.stdout.write('%s: %s\r\n' % header)
sys.stdout.write('\r\n')
sys.stdout.write(data)
sys.stdout.flush() def start_response(status, response_headers, exc_info=None):
if exc_info:
try:
# Re-raise original exception if headers sent
if headers_sent:
raise [exc_info[0],exc_info[1],exc_info[2]]
finally:
exc_info = None # avoid dangling circular ref
elif headers_set:
raise AssertionError("Headers already set!")
headers_set[:] = [status, response_headers]
return write result = application(environ, start_response)
try:
for data in result:
if data: # don't send headers until body appears
write(data)
if not headers_sent:
write('') # send headers now if body was empty
finally:
if hasattr(result, 'close'):
result.close() if __name__ == '__main__':
run_with_cgi(simple_app)

WSGI协议规定,application必须是一个callable对象,这意味这个对象可以是Python中的一个函数,也可以是一个实现了__call__方法的类的实例。比如这个:
class AppClass(object):
status = '200 OK'
response_headers = [('Content-type', 'text/plain')] def __call__(self, environ, start_response):
print(environ, start_response)
start_response(self.status, self.response_headers)
return ['Hello AppClass.__call__\n']
application = AppClass()

正在更新中...

吴裕雄--天生自然PythonDjangoWeb企业开发:框架基础和技术选型的更多相关文章

  1. 吴裕雄--天生自然PythonDjangoWeb企业开发:需求

    开发或者做一个项目,是要有一个需求过来的,而不是无缘无故的,启动一个项目,或者推动整个项目进行下一步迭代.这个需求可能是根据用户反馈增加的,可能是老板提出来的,也有可能是产品经理提出来的,但是无论是什 ...

  2. 吴裕雄--天生自然PythonDjangoWeb企业开发:Django文档阅读简介

    Django是基于MVC模式的框架,虽然也被称为“MTV”的模式,但是大同小异.对我们来说,需要了解的是无论是MVC模式还是MTV模式,甚至是其他的什么模式,都是为了解耦.把一个软件系统划分为一层一层 ...

  3. 吴裕雄--天生自然PythonDjangoWeb企业开发:学员管理系统- 前台

    开发首页 做一个简单的用户提交申请的表单页面. 首先在student/views.py文件中编写下面的代码: # -*- coding: utf-8 -*- from __future__ impor ...

  4. 吴裕雄--天生自然PythonDjangoWeb企业开发:学员管理系统后台

    需求 提供一个学员管理系统,一个前台页面,展示现有学员,并供新学员提交申请,一个后台,能够处理申请. pip install django==1.11.2 创建项目 使用控制台进入到一个目录下,具体是 ...

  5. 吴裕雄--天生自然PythonDjangoWeb企业开发:解决使用相对路径名导入包中子模块问题

    问题 将代码组织成包,想用import语句从另一个包名没有硬编码过的包中导入子模块. 解决方案

  6. 吴裕雄--天生自然PythonDjangoWeb企业开发:解决Pythonno module named "XX"问题

    在项目中加入 sys.path.append('你的django项目路径') sys.path.append('python的site-packages路径')

  7. 吴裕雄--天生自然PythonDjangoWeb企业开发:解决ModuleNotFoundError: No module named 'config'报错

    使用创建完模块应用之后python manage.py startapp test_app,您应该进入settings.py并将其注册到

  8. 吴裕雄--天生自然 R语言开发学习:R语言的安装与配置

    下载R语言和开发工具RStudio安装包 先安装R

  9. 吴裕雄--天生自然 R语言开发学习:数据集和数据结构

    数据集的概念 数据集通常是由数据构成的一个矩形数组,行表示观测,列表示变量.表2-1提供了一个假想的病例数据集. 不同的行业对于数据集的行和列叫法不同.统计学家称它们为观测(observation)和 ...

随机推荐

  1. 每天进步一点点------入门视频采集与处理(显示YUV数据)

    做视频采集与处理,自然少不了要学会分析YUV数据.因为从采集的角度来说,一般的视频采集芯片输出的码流一般都是YUV数据流的形式,而从视频处理(例如H.264.MPEG视频编解码)的角度来说,也是在原始 ...

  2. [洛谷P4463] calc (生成函数)

    首先注意到题目中 \(a\) 数组是有序的,那我们只用算有序的方案乘上 \(n!\) 即可. 而此时的答案显然 \[Ans=[x^n](1+x)(1+2x)\dots (1+Ax)=\prod_{i= ...

  3. queue的使用-Hdu 1702

    ACboy needs your help again! Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  4. git按需过滤提交文件的一个细节

    问题场景 用git管理代码时,作为git小白的我总会遇到一些无法理解的问题,在请教了一些高手后终于解开了疑惑,参考以下场景: 1.比如我们已在电脑1上完成用vs编辑项目.添加.提交到服务器的完整流程, ...

  5. jvm系列(一)之内存模型

    JVM内存结构 Java内存模型是指Java虚拟机的内存模型,我们来看下Java内存模型的图片: VM内存模型主要分为三块:Java 堆内存(Heap).方法区(Non-Heap).JMV栈(JVM ...

  6. PB调用.NET类库详解

    要维护一个老的PB系统,有些地方用PB实在不方便,好在就张三.李四几个人用,每人装个.net框架. 设置.NET类COM可见 方式一:将整个程序集设成COM可见 方式二,只公开部分类 使用.Net框架 ...

  7. 从 0 到 1:Apache APISIX 的 Apache 之路

    2019 年 12 月 14 日,又拍云联合 Apache APISIX 社区举办 API 网关与高性能服务最佳实践丨Open Talk 广州站活动,本次活动,邀请了来自Apache APISIX.又 ...

  8. idea设置单行注释格式(包括配置文件)

    idea中文件单行注释默认在行首位置 修改方法:进入File-->Settings-->Editor-->Code Style-->Java,修改Code Generation ...

  9. C# 抗变与协变的理解

    我们知道 方法的参数是协变的: void display(shape o) 如果类Rectangle 继承于shape类,那我们可以给该方法传入Rectangle类的实例. 而方法的返回类型是抗变的, ...

  10. 线段树——I hate it

    [问题描述]     很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感.    不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模 ...