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中sets模块的用法实例
Sep 30 Python
python实现通过pil模块对图片格式进行转换的方法
Mar 24 Python
详解python时间模块中的datetime模块
Jan 13 Python
Python类属性的延迟计算
Oct 22 Python
python中MethodType方法介绍与使用示例
Aug 03 Python
详解python eval函数的妙用
Nov 16 Python
python批量修改文件编码格式的方法
May 31 Python
python正则表达式之对号入座篇
Jul 24 Python
Python global全局变量函数详解
Sep 18 Python
python中的列表与元组的使用
Aug 08 Python
Python自动化之UnitTest框架实战记录
Sep 08 Python
Python 虚拟环境工作原理解析
Dec 24 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实现模仿socket请求返回页面的方法
2014/11/04 PHP
ThinkPHP在Cli模式下使用模板引擎的方法
2015/09/25 PHP
用于节点操作的API,颠覆原生操作HTML DOM节点的API
2010/12/11 Javascript
javascript 图片裁剪技巧解读
2012/11/15 Javascript
使用闭包对setTimeout进行简单封装避免出错
2013/07/10 Javascript
js图片延迟技术一般的思路与示例
2014/03/20 Javascript
javascript实现校验文件上传控件实例
2015/04/20 Javascript
js学习阶段总结(必看篇)
2016/06/16 Javascript
Angularjs 创建可复用组件实例代码
2016/10/09 Javascript
使用AngularJS2中的指令实现按钮的切换效果
2017/03/27 Javascript
JavaScript 自定义事件之我见
2017/09/25 Javascript
Vue组件通信的四种方式汇总
2018/02/08 Javascript
Vue引入jquery实现平滑滚动到指定位置
2018/05/09 jQuery
对angularJs中自定义指令replace的属性详解
2018/10/09 Javascript
Nodejs实现用户注册功能
2019/04/14 NodeJs
JavaScript中关于base64的一些事
2019/05/06 Javascript
[01:08:00]Fnatic vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
跟老齐学Python之编写类之四再论继承
2014/10/11 Python
Python中的with语句与上下文管理器学习总结
2016/06/28 Python
python计算日期之间的放假日期
2018/06/05 Python
5分钟 Pipenv 上手指南
2018/12/20 Python
ActiveMQ:使用Python访问ActiveMQ的方法
2019/01/30 Python
Django为窗体加上防机器人的验证码功能过程解析
2019/08/14 Python
6种非常炫酷的CSS3按钮边框动画特效
2016/03/16 HTML / CSS
HTML5播放实现rtmp流直播
2020/06/16 HTML / CSS
理工科学生的自我评价
2013/12/15 职场文书
公司道歉信范文
2014/01/09 职场文书
领导干部群众路线个人对照检查材料思想汇报
2014/09/30 职场文书
民政局离婚协议书范本
2014/10/20 职场文书
年会邀请函范文
2015/01/30 职场文书
幼儿园感恩节活动总结
2015/03/24 职场文书
暗恋桃花源观后感
2015/06/12 职场文书
保险公司增员口号
2015/12/25 职场文书
导游经典开场白——导游词
2019/04/17 职场文书
windows server 2012安装FTP并配置被动模式指定开放端口
2022/06/10 Servers
css中:last-child不生效的解决方法
2022/08/05 HTML / CSS