文章目录

  • 1. HTTP协议
  • 2. Web服务器
  • 3. 静态服务器
    • 创建 web_server.py
  • 4. WSGI 接口
    • 4.1 CGI 通用网关接口
    • 4.2 WSGI
    • 4.3 定义 WSGI 接口
    • 4.4 运行 WSGI 服务

learning from 《python web开发从入门到精通》

1. HTTP协议

  • 应用层最主要的协议:HTTP协议(HyperText Transfer Protocol 超文本传输协议)
  • 用户访问网站时,用户浏览器是客户端(向服务器发请求),网站被称为服务器(收到请求,处理后的响应传给客户端),此过程通过 HTTP 协议实现
  • 利用 TCP 在两台计算机(如Web服务器,客户端)之间传输信息,客户端使用 web浏览器发送 HTTP 请求给 web 服务器,服务器发送响应给客户端

2. Web服务器

当在浏览器中输入 url 后:

  1. 浏览器请求 DNS 服务器,进行域名解释,获得 站点 IP 地址
  2. 发送一个 HTTP Request 请求 给拥有该 IP 的主机
  3. 收到服务器返回的 HTTP Response响应,浏览器渲染效果后呈现给用户

Web 服务器工作原理:

  • 建立连接:客户端通过 TCP/IP 协议建立到服务器的 TCP 连接
  • 请求过程:客户端向服务器发送 HTTP协议请求包,请求资源
  • 应答过程:服务器向客户端发送 HTTP协议应答包,如果资源包含动态语言内容,会先进行处理,得到的数据返回客户端,客户端解释 HTML 渲染在屏幕上
  • 关闭连接:断开客户端和服务器

常用请求方法:

  • GET:请求指定页面
  • POST:提交数据(表单或者文件等)
  • HEAD:类似GET,但仅仅获取报头
  • PUT:取代服务器上的指定文档内容
  • DELETE:服务器删除指定页面
  • OPTIONS:允许客户端查看服务器性能

返回状态码:

  • 1**:请求收到,继续处理
  • 2**:成功返回响应
  • 3**:重定向,为了完成请求,必须进一步执行的动作
  • 4**:客户端错误,如语法错误,或者请求无法实现
  • 5**:服务器错误,服务器不能实现一种明显无效的请求

浏览器 按 F12 可以查看相关信息

3. 静态服务器

  • 纯粹的 HTML 页面被称为 静态页面

例子:创建一个静态服务器,通过该服务器可以访问包含两个静态页面的网站

  • 导航栏的网页 simple_navbar.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>使用bootstrap框架制作导航栏</title><link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.2/css/bootstrap.css" rel="stylesheet"><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/popper.js/2.9.2/cjs/popper-base.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.2/js/bootstrap.js"></script></head>
<body><nav class="navbar navbar-expand-sm navbar-light bg-light"><div class="container-fluid"><a class="navbar-brand" href="https://michael.blog.csdn.net/">我的导航</a><button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button><div class="collapse navbar-collapse" id="navbarSupportedContent"><ul class="navbar-nav me-auto mb-2 mb-lg-0"><li class="nav-item"><a class="nav-link active" aria-current="page" href="https://michael.blog.csdn.net/">主页</a></li><li class="nav-item"><a class="nav-link" href="#">链接</a></li><li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button"data-bs-toggle="dropdown" aria-expanded="false">关于作者</a><ul class="dropdown-menu" aria-labelledby="navbarDropdown"><li><a class="dropdown-item" href="#">简历</a></li><li><a class="dropdown-item" href="#">项目</a></li><li><hr class="dropdown-divider"></li><li><a class="dropdown-item" href="contact.html">联系方式</a></li></ul></li><li class="nav-item"><a class="nav-link disabled">商城</a></li></ul><form class="d-flex"><input class="form-control me-2" type="search" placeholder="输入你的关键词" aria-label="Search"><button class="btn btn-outline-success" type="submit">站内搜索</button></form></div></div>
</nav></body>
</html>
  • contact.html,在上面的基础上,添加一些额外的联系信息
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>联系michael</title><link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.2/css/bootstrap.css" rel="stylesheet"><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/popper.js/2.9.2/cjs/popper-base.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.2/js/bootstrap.js"></script></head>
<body><nav class="navbar navbar-expand-sm navbar-light bg-light"><div class="container-fluid"><a class="navbar-brand" href="https://michael.blog.csdn.net/">我的导航</a><button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button><div class="collapse navbar-collapse" id="navbarSupportedContent"><ul class="navbar-nav me-auto mb-2 mb-lg-0"><li class="nav-item"><a class="nav-link active" aria-current="page" href="https://michael.blog.csdn.net/">主页</a></li><li class="nav-item"><a class="nav-link" href="#">链接</a></li><li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button"data-bs-toggle="dropdown" aria-expanded="false">关于作者</a><ul class="dropdown-menu" aria-labelledby="navbarDropdown"><li><a class="dropdown-item" href="#">简历</a></li><li><a class="dropdown-item" href="#">项目</a></li><li><hr class="dropdown-divider"></li><li><a class="dropdown-item" href="contact.html">联系方式</a></li></ul></li><li class="nav-item"><a class="nav-link disabled">商城</a></li></ul><form class="d-flex"><input class="form-control me-2" type="search" placeholder="输入你的关键词" aria-label="Search"><button class="btn btn-outline-success" type="submit">站内搜索</button></form></div></div>
</nav><div class="bs-docs-header" id="content" tabindex="-1"><div class="container"><h1> 联系michael </h1><div class="lead"><address>电子邮件:<strong>michael@xxx.com</strong><br>地址:地球村86号<br>邮政编码:<strong>xxxxxx</strong><br><abbr title="Phone">联系电话:</abbr> 1234567890</address></div></div>
</div></body>
</html>

创建 web_server.py

实现客户端和服务器的 HTTP 通信

注:由于 HTML 里面写了很多下载的 css 文件地址,路径总是报错,最后还是 建议引用 CDN 写法,相关库地址查询https://www.bootcdn.cn/

<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.2/css/bootstrap.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/popper.js/2.9.2/cjs/popper-base.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.2/js/bootstrap.js"></script>
import socket
import re
from multiprocessing import Process  # 多线程HTML_ROOT_DIR = './'  # 设置静态页面的根目录class HTTPServer:def __init__(self):self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)def start(self):self.server_socket.listen(128)  # 最大连接数128print("服务器等待客户端连接...")while True:client_socket, client_addr = self.server_socket.accept()  # 建立客户端连接print("[%s, %s]用户连接上了" % client_addr)handle_client_process = Process(target=self.handle_client, args=(client_socket,))# 实例化线程,第一个参数调用函数 ,第二个参数 传递给前者的参数,元组形式handle_client_process.start()  # 开启线程client_socket.close()  # 关闭客户端socketdef handle_client(self, client_socket):# 处理客户端请求request_data = client_socket.recv(1024)  # 接收客户端请求print("request data:", request_data)request_lines = request_data.splitlines()  # 按行分割for line in request_lines:print(line)  # 输出信息request_start_line = request_lines[0]  # 获取请求报文print("*" * 10)print(request_start_line.decode("utf-8"))file_name = re.match(r"\w+ +(/[^ ]*) ", request_start_line.decode("utf-8")).group(1)# 使用正则表达式,提取请求的文件名,group(1) 列出第一个括号匹配部分if file_name == "/":file_name = "/simple_navbar.html"try:# 尝试打开文件file = open(HTML_ROOT_DIR + file_name, "rb")except IOError:# 读取文件失败,返回404response_start_line = "HTTP/1.1 404 Not Found\r\n"response_headers = "Server: Michael server\r\n"response_body = "The file %s is not found! please check again!" % (HTML_ROOT_DIR + file_name)else:file_data = file.read()file.close()# 构造响应数据response_start_line = "HTTP/1.1 200 OK\r\n"response_headers = "Server: Michael server\r\n"response_body = file_data.decode("utf-8")# 拼接返回数据response = response_start_line + response_headers + "\r\n" + response_bodyprint("response data:", response)client_socket.send(bytes(response, "utf-8"))  # 向客户端发送响应数据client_socket.close()  # 关闭客户端连接def bind(self, port):self.server_socket.bind(("127.0.0.1", port))def main():http_server = HTTPServer()http_server.bind(8000)http_server.start()if __name__ == "__main__":main()



4. WSGI 接口

上面实现了一个静态服务器,但是现在很少使用,更多的是使用 动态页面,实现交互性

  • 例如,注册登录网站,用户输入数据,web服务器不处理用户数据(不是它的职责),CGI 诞生

4.1 CGI 通用网关接口

  • Common Gateway Interface 是一段程序,运行在服务器上
  • web 服务器将请求发送给 CGI 应用程序,再将 CGI 动态生成的 HTML 页面发送回客户端

CGI 局限性:创建完解释器进程,用完就抛弃,大量的请求导致服务器停机

  • CGI 加强版 FastCGI 出现,其使用 进程/线程池 来处理一连串的请求
    减少了 网页服务器CGI 程序之间 交互的开销

4.2 WSGI

  • FastCGI 标准下写异步的 Web 服务不太方便,WSGI (Web Server Gateway Interface 服务器网关接口) 出现

下图 from https://www.cnblogs.com/wilber2013/p/4763067.html

4.3 定义 WSGI 接口

最简单的web版本 hello world

def applications(environ, start_response):start_response('200 OK', [('Content-Type', 'text/html')])return [b'<h1>Hello, Michael!</h1>']

上面函数就是符合 WSGI 标准的一个 HTTP 处理函数

  • environ :一个所有 HTTP 请求信息的字典对象
  • start_response:一个发送 HTTP 响应的函数

好处:web 解析 和 应用程序逻辑 分离,可以各自做自己擅长的事

python 内置了 WSGI:wsgiref 模块(它没有考虑运行效率,仅供开发测试)

4.4 运行 WSGI 服务

  • wsgi_app.py
# wsgi 应用程序
def app(environ, start_response):# 响应信息start_response('200 OK', [('Content-Type', 'text/html')])file_name = environ['PATH_INFO'][1:] or 'simple_navbar.html'HTML_ROOT_DIR = './'try:# 打开文件file = open(HTML_ROOT_DIR + file_name, 'rb')except IOError:# 响应异常response_body = "{} not found".format(HTML_ROOT_DIR + file_name)else:# 读取文件file_data = file.read()file.close()# 构造响应数据response_body = file_data.decode('utf-8')return [response_body.encode('utf-8')]  # 返回数据
  • wsgi_server.py
# WSGI 服务器
from wsgiref.simple_server import make_server
from wsgi_app import app# 创建一个服务器,IP地址为空,端口号为8000,处理函数是app
httpd = make_server('', 8000, app)
print('Serving HTTP on port 8000...')
httpd.serve_forever()  # 开始监听HTTP请求

运行 wsgi_server.py ,在浏览器输入 http://127.0.0.1:8000/ 就可以访问网页了

python web开发 网络编程 HTTP协议、Web服务器、WSGI接口相关推荐

  1. 网络编程_HTTP协议_Web服务器_(TCP3次握手4次挥手,长短连接,伪静态、静态和动态)

    Python高级语法--网络编程--进阶学习笔记 文中案例参考: https://github.com/FangbaiZhang/Python_advanced_learning/tree/maste ...

  2. python web开发 网络编程 TCP/IP UDP协议

    文章目录 1. TCP/IP协议 1.1 IP协议 1.2 TCP协议 2. UDP协议 3. Socket 4. TCP编程 4.1 创建TCP服务器 4.2 创建TCP客户端 4.3 简易聊天工具 ...

  3. python学习(九) 网络编程学习--简易网站服务器

    python `网络编程`和其他语言都是一样的,服务器这块步骤为: `1. 创建套接字` `2. 绑定地址` `3. 监听该描述符的所有请求` `4. 有新的请求到了调用accept处理请求` Pyt ...

  4. Python四大主流网络编程框架

    目前Python的网络编程框架已经多达几十个,逐个学习它们显然不现实.但这些框架在系统架构和运行环境中有很多共通之处,本文带领读者学习基于Python网络框架开发的常用知识,及目前的4种主流Pytho ...

  5. python网络编程攻略-Python四大主流网络编程框架

    目前Python的网络编程框架已经多达几十个,逐个学习它们显然不现实.但这些框架在系统架构和运行环境中有很多共通之处,本文带领读者学习基于Python网络框架开发的常用知识,及目前的4种主流Pytho ...

  6. 您所应了解的Python四大主流网络编程框架

    本文内容摘录自<Python高效开发实战--Django.Tornado.Flask.Twisted>一书.该书分为三部分:第1部分是基础篇,带领初学者实践Python开发环境和掌握基本语 ...

  7. 02.iOS开发网络篇—HTTP协议

    iOS开发网络篇-HTTP协议 说明:apache tomcat服务器必须占用8080端口 一.URL 1.基本介绍 URL的全称是Uniform Resource Locator(统一资源定位符) ...

  8. (转)C#网络编程(订立协议和发送文件) - Part.4

    源码下载:http://www.tracefact.net/SourceCode/Network-Part4.rar C#网络编程(订立协议和发送文件) - Part.4 文件传输 前面两篇文章所使用 ...

  9. Web开发基本准则-55实录-Web访问安全

    Web开发工程师请阅读下面的前端开发准则,这是第一部分,强调了过去几年里我们注意到的Web工程师务须处理的Web访问安全基础点.尤其是一些从传统软件开发转入互联网开发的工程师,请仔细阅读,不要因为忽视 ...

最新文章

  1. 数据结构源码笔记(C语言):二路归并排序
  2. 用python计算贷款_Python基于Logistic回归建模计算某银行在降低贷款拖欠率的数据示例...
  3. ECC椭圆曲线算法(4)签名验证过程
  4. Android 4.4.2 动态添加JNI库方法记录 (二 app应用层)
  5. [原创]java获取word里面的文本
  6. mysql占用内存吗_mysql占多少内存
  7. 驾驶舱、移动端、分析报告,这几个可视化布局思路,拿来就能用
  8. php 用积分兑换_PHP积分兑换接口demo
  9. e盾服务端源码_原罪西游源码发布!!!
  10. Linux more和less
  11. 线性表部分知识点小结
  12. [C++]出错member access into incomplete type
  13. Python之面向对象2
  14. 《运算放大器权威指南》读书笔记(二)
  15. 独立博客大全的SWOT分析
  16. OpenG数组讲解之Filter 1D Array。
  17. 关于165的(ORCAP-1192)
  18. Ubuntu系统备份还原教程
  19. 实战!双硬盘安装图解!
  20. java加载图片的问题

热门文章

  1. TensorFlow 基本操作
  2. 机器学习之单标签多分类及多标签多分类
  3. C语言信息系统贴吧,急 c语言学生信息管理系统
  4. python中的魔术方法
  5. python静态方法,类方法,属性方法,实例方法
  6. oracle sql语句 从指定条数查询
  7. linux 最强shell,最牛B 的 Linux Shell 命令(一)
  8. 锐浪报表数据源access_kylin+SuperSet实现实时大数据报表的快速开发
  9. 第二季1:图像基础知识
  10. NVLink技术及影响解析