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 相关文章推荐
利用ctypes提高Python的执行速度
Sep 09 Python
Python用csv写入文件_消除空余行的方法
Jul 06 Python
pyqt5实现俄罗斯方块游戏
Jan 11 Python
Pytorch实现的手写数字mnist识别功能完整示例
Dec 13 Python
Python字典添加,删除,查询等相关操作方法详解
Feb 07 Python
Pytorch中的自动求梯度机制和Variable类实例
Feb 29 Python
python 函数嵌套及多函数共同运行知识点讲解
Mar 03 Python
vue常用指令代码实例总结
Mar 16 Python
windows10在visual studio2019下配置使用openCV4.3.0
Jul 14 Python
Python如何在bool函数中取值
Sep 21 Python
pandas针对excel处理的实现
Jan 15 Python
Python爬虫中urllib3与urllib的区别是什么
Jul 21 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面向对象全攻略 (七) 继承性
2009/09/30 PHP
PHP制作3D扇形统计图以及对图片进行缩放操作实例
2014/10/23 PHP
php操作mongoDB实例分析
2014/12/29 PHP
PHP读取文件内容的五种方式
2015/12/28 PHP
一波PHP中cURL库的常见用法代码示例
2016/05/06 PHP
PHP入门教程之数组用法汇总(创建,删除,遍历,排序等)
2016/09/11 PHP
laravel 自定义常量的两种方案
2019/10/14 PHP
详解jquery uploadify 上传文件
2013/11/09 Javascript
JavaScript使用replace函数替换字符串的方法
2015/04/06 Javascript
jQuery插件scroll实现无缝滚动效果
2015/04/27 Javascript
js中toString()和String()区别详解
2017/03/23 Javascript
jQuery.Ajax()的data参数类型详解
2017/07/23 jQuery
微信小程序顶部可滚动导航效果
2017/10/31 Javascript
element 结合vue 在表单验证时有值却提示错误的解决办法
2018/01/22 Javascript
bootstrap fileinput插件实现预览上传照片功能
2018/01/23 Javascript
Vue-cli3项目配置Vue.config.js实战记录
2018/07/29 Javascript
AngularJS发送异步Get/Post请求方法
2018/08/13 Javascript
深入理解Vue.js轻量高效的前端组件化方案
2018/12/10 Javascript
在Vue项目中使用snapshot测试的具体使用
2019/04/16 Javascript
vue操作动画的记录animate.css实例代码
2019/04/26 Javascript
在Vue中使用antv的示例代码
2020/06/29 Javascript
vue任意关系组件通信与跨组件监听状态vue-communication
2020/10/18 Javascript
浅谈vant组件Picker 选择器选单选问题
2020/11/04 Javascript
[47:21]Liquid vs TNC Supermajor 胜者组 BO3 第一场 6.4
2018/06/05 DOTA
[50:38]DOTA2-DPC中国联赛 正赛 Phoenix vs CDEC BO3 第二场 3月7日
2021/03/11 DOTA
Python StringIO模块实现在内存缓冲区中读写数据
2015/04/08 Python
python+opencv+caffe+摄像头做目标检测的实例代码
2018/08/03 Python
PyQt5实现类似别踩白块游戏
2019/01/24 Python
Python 保持登录状态进行接口测试的方法示例
2019/08/06 Python
python web框架Flask实现图形验证码及验证码的动态刷新实例
2019/10/14 Python
Python使用指定字符长度切分数据示例
2019/12/05 Python
Python多进程编程multiprocessing代码实例
2020/03/12 Python
Matplotlib中%matplotlib inline如何使用
2020/07/28 Python
咖啡店自主创业商业计划书
2014/01/22 职场文书
2015年元旦活动总结
2014/05/09 职场文书
2015试用期转正工作总结
2014/12/12 职场文书