简单的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. IDE - IDEA - tab - 方法相关的移动

    1. 概述 标题可能会改 一个 tab 里方法相关的操作 2. 前提 以默认的模式编辑 tab 对我来说, 就关掉 vim 插件 3. 操作 1. 查看文件结构 概述 唤出当前文件的 结构 唤出后可以 ...

  2. C#中的循环:while do...while for

    循环:重复将相同或类似规律的代码进行反复执行 减少代码冗余  可维护  可扩展 while(bool) { ...; } 代码块中可以使用break或者continue中断 break:中断整个循环 ...

  3. 【转】VMware Converter迁移linux系统虚拟机

    原始出处 今天接到一个需求,迁移一台linux的业务系统到vCenter云管理平台,其中遇到一些问题,于是进行了排错,这个过程与大家分享,下面把整个步骤进行截图说明. 1. 首先,登录到VMware  ...

  4. SQL Server不同服务器不同数据库间的操作

    什么是跨服务器操作? 跨服务器操作就是可以在本地连接到远程服务器上的数据库,可以在对方的数据库上进行相关的数据库操作,比如增删改查. 为什么要进行跨服务器操作 随着数据量的增多,业务量的扩张,需要在不 ...

  5. HGAME 2020 misc

    week1 每日推荐 拿到Wireshark capture file后,按常规思路,用foremost命令拿到一个加密的压缩包,之后文件->导出对象->http,看到最大的一个文件里面最 ...

  6. wordpress Error establishing a database connection问题

    最近这场大雨,快把帝都给淹了,我也快被这不定向问题折磨疯了,本来把项目放在A服务器,nginx ,php7,mysql,然后换到了B服务器,环境一模一样,结果呢,传上去就出现了 哎,话说我的配置也没啥 ...

  7. 80端口被system占用

    # 开始 今天配置wampserver 3.0.6的时候 发现右下角的图标一直是红色的 经验告诉我两个服务都没有运行 # 解决思路 wampserver有两个服务 一个是 Apache 服务 一个是 ...

  8. 从0到1了解 CI/CD

    现代软件开发的需求加上部署到不同基础设施的复杂性使得创建应用程序成为一个繁琐的过程.当应用程序出现规模性增长,开发团队人员变得更分散时,快速且不断地生产和发布软件的流程将会变得更加困难.为了解决这些问 ...

  9. python linux windows 历史版本下载

    Index of /ftp/python/ ../ 2.0/ 14-Feb-2019 14:53 - 2.0.1/ 06-Aug-2001 02:14 - 2.1/ 06-Aug-2001 02:14 ...

  10. 获取SqlServer存储过程定义的三种方法

    declare @p_text varchar(max) SELECT @p_text= text FROM syscomments WHERE id = ( SELECT id FROM sysob ...