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 相关文章推荐
sqlalchemy对象转dict的示例
Apr 22 Python
Python Web框架Flask中使用七牛云存储实例
Feb 08 Python
Python时间戳使用和相互转换详解
Dec 11 Python
python 输出上个月的月末日期实例
Apr 11 Python
查看django执行的sql语句及消耗时间的两种方法
May 29 Python
Python读取英文文件并记录每个单词出现次数后降序输出示例
Jun 28 Python
python3中替换python2中cmp函数的实现
Aug 20 Python
python GUI库图形界面开发之PyQt5计数器控件QSpinBox详细使用方法与实例
Feb 28 Python
Django实现将一个字典传到前端显示出来
Apr 03 Python
Python-jenkins模块之folder相关操作介绍
May 12 Python
Opencv图像处理:如何判断图片里某个颜色值占的比例
Jun 03 Python
利用Python过滤相似文本的简单方法示例
Feb 03 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获取MAC地址的具体实例
2013/12/13 PHP
PHP static局部静态变量和全局静态变量总结
2014/03/02 PHP
php中curl使用指南
2015/02/05 PHP
WordPress中转义HTML与过滤链接的相关PHP函数使用解析
2015/12/22 PHP
ThinkPHP设置禁止百度等搜索引擎转码(简单实用)
2016/02/15 PHP
详解php中反射的应用
2016/03/15 PHP
js 判断 enter 事件
2009/02/12 Javascript
firefox插件Firebug的使用教程
2010/01/02 Javascript
jQuery 源码分析笔记(6) jQuery.data
2011/06/08 Javascript
jQuery EasyUI API 中文文档 - TimeSpinner时间微调器
2011/10/23 Javascript
js 获取屏幕各种宽高的方法(浏览器兼容)
2013/05/15 Javascript
简单方法判断JavaScript对象为null或者属性为空
2014/09/26 Javascript
详解jQuery向动态生成的内容添加事件响应jQuery live()方法
2015/11/02 Javascript
走进AngularJs之过滤器(filter)详解
2017/02/17 Javascript
JS实现网页抢购功能(触发,终止脚本)
2017/11/27 Javascript
vue之浏览器存储方法封装实例
2018/03/15 Javascript
Vue唯一可以更改vuex实例中state数据状态的属性对象Mutation的讲解
2019/01/18 Javascript
微信小程序开发之map地图组件定位并手动修改位置偏差
2019/08/17 Javascript
超简单的微信小程序轮播图
2019/11/22 Javascript
vue中选中多个选项并且改变选中的样式的实例代码
2020/09/16 Javascript
详解Python中用于计算指数的exp()方法
2015/05/14 Python
LRUCache的实现原理及利用python实现的方法
2017/11/21 Python
python初学之用户登录的实现过程(实例讲解)
2017/12/23 Python
代码讲解Python对Windows服务进行监控
2018/02/11 Python
python3 破解 geetest(极验)的滑块验证码功能
2018/02/24 Python
Python实现批量读取图片并存入mongodb数据库的方法示例
2018/04/02 Python
flask框架url与重定向操作实例详解
2020/01/25 Python
pycharm 如何取消连按两下shift出现的全局搜索
2021/01/15 Python
用HTML5中的Canvas结合公式绘制粒子运动的教程
2015/05/08 HTML / CSS
描述Cookie和Session的作用,区别和各自的应用范围,Session工作原理
2015/03/25 面试题
法制宣传实施方案
2014/03/13 职场文书
元旦晚会主持词
2014/03/24 职场文书
事业单位人员的自我评价范文
2014/09/21 职场文书
2015年手术室工作总结
2015/05/11 职场文书
论文致谢词范文
2015/05/14 职场文书
街道办残联2016年助残日活动总结
2016/04/01 职场文书