吴裕雄--天生自然PythonDjangoWeb企业开发:框架基础和技术选型

2023-06-14,,

简单的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企业开发:框架基础和技术选型的相关教程结束。

《吴裕雄--天生自然PythonDjangoWeb企业开发:框架基础和技术选型.doc》

下载本文的Word格式文档,以方便收藏与打印。