python实现静态web服务器


Posted in Python onSeptember 03, 2019

HTTP协议简介

HTTP请求

1:浏览器首先向服务器发送HTTP请求,请求包括:

方法:GET还是POST,GET仅请求资源,POST会附带用户数据;
路径:/full/url/path;
域名:由Host头指定:Host: www.sina.com以及其他相关的Header;
如果是POST,那么请求还包括一个Body,包含用户数据

2:服务器向浏览器返回HTTP响应,响应包括:

响应代码:200表示成功,3xx表示重定向,4xx表示客户端发送的请求有错误,5xx表示服务器端处理时发生了错误;
响应类型:由Content-Type指定;
以及其他相关的Header;
通常服务器的HTTP响应会携带内容,也就是有一个Body,包含响应的内容,网页的HTML源码就在Body中。

3:如果浏览器还需要继续向服务器请求其他资源,比如图片,就再次发出HTTP请求,重复步骤1、2。

Web采用的HTTP协议采用了非常简单的请求-响应模式,从而大大简化了开发。当我们编写一个页面时,我们只需要在HTTP请求中把HTML发送出去,不需要考虑如何附带图片、视频等,浏览器如果需要请求图片和视频,它会发送另一个HTTP请求,因此,一个HTTP请求只处理一个资源(此时就可以理解为TCP协议中的短连接,每个链接只获取一个资源,如需要多个就需要建立多个链接)

HTTP格式

每个HTTP请求和响应都遵循相同的格式,一个HTTP包含Header和Body两部分,其中Body是可选的。
HTTP协议是一种文本协议,所以,它的格式也非常简单。

1 HTTP GET请求的格式:

GET /path HTTP/1.1
 Header1: Value1
 Header2: Value2
 Header3: Value3

每个Header一行一个,换行符是\r\n。

2 HTTP POST请求的格式:

POST /path HTTP/1.1
 Header1: Value1
 Header2: Value2
 Header3: Value3

 body data goes here...

3 HTTP响应的格式:

200 OK
 Header1: Value1
 Header2: Value2
 Header3: Value3

 body data goes here...

HTTP响应如果包含body,也是通过\r\n\r\n来分隔的。
请再次注意,Body的数据类型由Content-Type头来确定,如果是网页,Body就是文本,如果是图片,Body就是图片的二进制数据。
当存在Content-Encoding时,Body数据是被压缩的,最常见的压缩方式是gzip,所以,看到Content-Encoding: gzip时,需要将Body数据先解压缩,才能得到真正的数据。压缩的目的在于减少Body的大小,加快网络传输。

demo:静态web服务器

import socket
import re
import time


def service_client(new_socket):
 """为这个客户端服务"""

 # 1.接收浏览器发送过来的请求,即http请求
 # GET / HTTP/1.1
 # --------
 request = new_socket.recv(1024).decode('utf-8')

 # 判断客户端意外断开链接返回空字符串
 if not request:
  # 关闭套接字并退出
  new_socket.close()
  print("==="*30)
  return

 # 分隔套接字
 request_lines = request.splitlines()
 print()
 print(">"*20)
 print(request_lines)

 file_name = ""
 ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0])
 if ret:
  file_name = ret.group(1)
  if file_name == "/":
   file_name = "/index.html"

 # 2.返回http格式数据 给浏览器
 try:
  f = open("./html" + file_name, "rb")
 except:
  response = "HTTP/1.1 404 NOT FOUND\r\n"
  response += "Content-Type:text/html;charset=utf-8\r\n"
  response += "\r\n"
  response += "<h1>404 not found <br> 没有发现所请求资源</h1>"
  response += str(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
  new_socket.send(response.encode('utf-8'))
 else:
  html_content = f.read()
  f.close()
  # 2.1准备发送给浏览器的数据---header
  response = "HTTP/1.1 200 OK\r\n"
  response += "\r\n"
  # 2.2准备发送给浏览器的数据 ---body
  # 将response header发送给浏览器
  new_socket.send(response.encode("utf-8"))
  # 将response body发送给浏览器
  new_socket.send(html_content)

 # 关闭套接字
 new_socket.close()


def main():
 """用来完成整体的控制"""
 # 1.创建套接字
 tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 # 端口复用
 tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 # 2.绑定
 tcp_server_socket.bind(("", 7890))
 # 3.变为套接字
 tcp_server_socket.listen(128)

 while True:
  # 4.等待客户端的链接
  new_socket, client_addr = tcp_server_socket.accept()

  print(client_addr)

  # 5.为这个客户端服务
  service_client(new_socket)

 # 关闭监听套接字
 tcp_server_socket.close()


if __name__ == '__main__':
 main()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 控制语句
Nov 03 Python
python选择排序算法的实现代码
Nov 21 Python
Python中的fileinput模块的简单实用示例
Jul 09 Python
解决csv.writer写入文件有多余的空行问题
Jul 06 Python
python3 面向对象__类的内置属性与方法的实例代码
Nov 09 Python
python配置grpc环境
Jan 01 Python
详解Django模版中加载静态文件配置方法
Jul 21 Python
Python 时间戳之获取整点凌晨时间戳的操作方法
Jan 28 Python
利用python制作拼图小游戏的全过程
Dec 04 Python
Python djanjo之csrf防跨站攻击实验过程
May 14 Python
python使用BeautifulSoup 解析HTML
Apr 24 Python
python神经网络学习 使用Keras进行简单分类
May 04 Python
Python的Lambda函数用法详解
Sep 03 #Python
Python获取一个用户名的组ID过程解析
Sep 03 #Python
python多线程实现TCP服务端
Sep 03 #Python
Python实现多线程/多进程的TCP服务器
Sep 03 #Python
python+selenium 点击单选框-radio的实现方法
Sep 03 #Python
使用OpCode绕过Python沙箱的方法详解
Sep 03 #Python
python实现单链表的方法示例
Sep 03 #Python
You might like
PHP防止注入攻击实例分析
2014/11/03 PHP
ThinkPHP中__initialize()和类的构造函数__construct()用法分析
2014/11/29 PHP
CodeIgniter视图使用注意事项
2016/01/20 PHP
php上传图片并给图片打上透明水印的代码
2010/06/07 Javascript
基于JQuery制作的产品广告效果
2010/12/08 Javascript
myeclipse安装jQuery插件的方法
2011/03/29 Javascript
artdialog的图片/标题以及关闭按钮不显示的解决方法
2013/06/27 Javascript
如何设置iframe高度自适应在跨域情况下的可用方法
2013/09/06 Javascript
jQuery中使用data()方法读取HTML5自定义属性data-*实例
2014/04/11 Javascript
JavaScript中判断原生函数检查function是否是原生代码
2014/09/09 Javascript
纯JavaScript代码实现移动设备绘图解锁
2015/10/16 Javascript
原生javascript 学习之js变量全面了解
2016/07/14 Javascript
实现隔行换色效果的两种方式【实用】
2016/11/27 Javascript
Vue.js学习之过滤器详解
2017/01/22 Javascript
vue实现一个移动端屏蔽滑动的遮罩层实例
2017/06/08 Javascript
bootstrap switch开关组件使用方法详解
2017/08/22 Javascript
代码实例ajax实现点击加载更多数据图片
2018/10/12 Javascript
JavaScript实现选项卡效果的分析及步骤
2019/04/16 Javascript
[01:03:51]2018DOTA2亚洲邀请赛 4.7 淘汰赛 VP vs LGD 第三场
2018/04/09 DOTA
[41:13]完美世界DOTA2联赛PWL S2 Forest vs Rebirth 第一场 11.20
2020/11/20 DOTA
python自定义解析简单xml格式文件的方法
2015/05/11 Python
Python设计模式中单例模式的实现及在Tornado中的应用
2016/03/02 Python
深入浅出分析Python装饰器用法
2017/07/28 Python
Python实现扩展内置类型的方法分析
2017/10/16 Python
Python Numpy库datetime类型的处理详解
2019/07/13 Python
10个python3常用排序算法详细说明与实例(快速排序,冒泡排序,桶排序,基数排序,堆排序,希尔排序,归并排序,计数排序)
2020/03/17 Python
Python批量安装卸载1000个apk的方法
2020/04/10 Python
24个canvas基础知识小结
2014/12/17 HTML / CSS
简约控的天堂:The Undone
2016/12/21 全球购物
百丽国际旗下购物网站:优购
2017/02/28 全球购物
初级会计求职信范文
2014/02/15 职场文书
人力资源部经理助理岗位职责
2014/03/04 职场文书
干部下基层实施方案
2014/03/14 职场文书
安全环保标语
2014/06/09 职场文书
团代会开幕词
2015/01/28 职场文书
canvas绘制折线路径动画实现
2021/05/12 Javascript