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将人民币转换大写的脚本代码
Feb 10 Python
深入理解Python中的元类(metaclass)
Feb 14 Python
Python比较两个图片相似度的方法
Mar 13 Python
python下实现二叉堆以及堆排序的示例
Sep 29 Python
python版学生管理系统
Jan 10 Python
python在非root权限下的安装方法
Jan 23 Python
人工神经网络算法知识点总结
Jun 11 Python
Form表单及django的form表单的补充
Jul 25 Python
python数据类型之间怎么转换技巧分享
Aug 20 Python
python图像处理模块Pillow的学习详解
Oct 09 Python
python MultipartEncoder传输zip文件实例
Apr 07 Python
python中用Scrapy实现定时爬虫的实例讲解
Jan 18 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 破解防盗链图片函数
2008/12/09 PHP
php通过文件头检测文件类型通用代码类(zip,rar等)
2010/10/19 PHP
thinkPHP的Html模板标签使用方法
2012/11/13 PHP
IIS+fastcgi下PHP运行超时问题的解决办法详解
2013/06/20 PHP
PHP PDO fetch 模式各种参数的输出结果一览
2015/01/07 PHP
PHP实现数据分页显示的简单实例
2016/05/26 PHP
PHP利用Cookie设置用户30分钟未操作自动退出功能
2017/07/03 PHP
Jquery实现简单的动画效果代码
2012/03/18 Javascript
JS定时刷新页面及跳转页面的方法
2013/07/04 Javascript
ff下JQuery无法监听input的keyup事件的解决方法
2013/12/12 Javascript
JS数组的遍历方式for循环与for...in
2014/07/31 Javascript
详解JavaScript中双等号引起的隐性类型转换
2016/05/30 Javascript
Node.js的Koa框架上手及MySQL操作指南
2016/06/13 Javascript
微信小程序首页的分类功能和搜索功能的实现思路及代码详解
2018/09/11 Javascript
基于three.js实现的3D粒子动效实例代码
2019/04/09 Javascript
详解vue父子组件关于模态框状态的绑定方案
2019/06/05 Javascript
jQuery实现王者荣耀手风琴效果
2020/01/17 jQuery
JavaScript数组去重实现方法小结
2020/01/17 Javascript
Js图片点击切换轮播实现代码
2020/07/27 Javascript
[05:05]DOTA2亚洲邀请赛 战队出场仪式
2015/02/07 DOTA
[01:00:12]2018DOTA2亚洲邀请赛 4.7 淘汰赛 VP vs LGD 第一场
2018/04/09 DOTA
采用python实现简单QQ单用户机器人的方法
2014/07/03 Python
Python实现SVN的目录周期性备份实例
2015/07/17 Python
Python使用Turtle模块绘制五星红旗代码示例
2017/12/11 Python
Python3非对称加密算法RSA实例详解
2018/12/06 Python
Python3.6中Twisted模块安装的问题与解决
2019/04/15 Python
Jupyter notebook如何修改平台字体
2020/05/13 Python
python3.7.3版本和django2.2.3版本是否可以兼容
2020/09/01 Python
CSS3 translate导致字体模糊的实例代码
2019/08/30 HTML / CSS
2014年团队工作总结
2014/11/24 职场文书
八年级上册语文教学计划
2015/01/22 职场文书
外贸采购员岗位职责
2015/04/03 职场文书
总结高并发下Nginx性能如何优化
2021/11/01 Servers
Python+Tkinter制作专属图形化界面
2022/04/01 Python
Nginx 匹配方式
2022/05/15 Servers
基于docker安装zabbix的详细教程
2022/06/05 Servers