主要内容:

  • 1.http协议
  • 2.web框架
  • 3.Django

1.http协议

1.1 http协议的简介

  • 超文本传输协议(英文:Hyper Text Transfer Protocol,HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。HTTP有很多应用,但最著名的是用于web浏览器和web服务器之间的双工通信。
  • HTTP的发展是由蒂姆·伯纳斯-李于1989年在欧洲核子研究组织(CERN)所发起。HTTP的标准制定由万维网协会(World Wide Web Consortium,W3C)和互联网工程任务组(Internet Engineering Task Force,IETF)进行协调,最终发布了一系列的RFC,其中最著名的是1999年6月公布的 RFC 2616,定义了HTTP协议中现今广泛使用的一个版本——HTTP 1.1。
  • 2014年12月,互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis(httpbis)工作小组将HTTP/2标准提议递交至IESG进行讨论,于2015年2月17日被批准。 HTTP/2标准于2015年5月以RFC 7540正式发表,取代HTTP 1.1成为HTTP的实现标准。

1.2 http协议的概述

  • HTTP是一个客户端终端(用户)和服务器端(网站)请求和应答的标准(TCP)。通过使用网页浏览器、网络爬虫或者其它的工具,客户端发起一个HTTP请求到服务器上指定端口(默认端口为80)。我们称这个客户端为用户代理程序(user agent)。应答的服务器上存储着一些资源,比如HTML文件和图像。我们称这个应答服务器为源服务器(origin server)。在用户代理和源服务器中间可能存在多个“中间层”,比如代理服务器、网关或者隧道(tunnel)。
  • 尽管TCP/IP协议是互联网上最流行的应用,HTTP协议中,并没有规定必须使用它或它支持的层。事实上,HTTP可以在任何互联网协议上,或其他网络上实现。HTTP假定其下层协议提供可靠的传输。因此,任何能够提供这种保证的协议都可以被其使用。因此也就是其在TCP/IP协议族使用TCP作为其传输层。
  • 通常,由HTTP客户端发起一个请求,创建一个到服务器指定端口(默认是80端口)的TCP连接。HTTP服务器则在那个端口监听客户端的请求。一旦收到请求,服务器会向客户端返回一个状态,比如"HTTP/1.1 200 OK",以及返回的内容,如请求的文件、错误消息、或者其它信息。

1.3 http工作原理

HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。

以下是 HTTP 请求/响应的步骤:

  • 1. 客户端连接到Web服务器
  • 一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如,http://www.luffycity.com。
  • 2. 发送HTTP请求
  • 通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。
  • 3. 服务器接受请求并返回HTTP响应
  • Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。
  • 4. 释放连接TCP连接
  • 若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
  • 5. 客户端浏览器解析HTML内容
  • 客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。

在浏览器地址栏键入URL,按下回车之后会经历以下流程:

  • 浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
  • 解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接;
  • 浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;
  • 服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;
  • 释放 TCP连接;
  • 浏览器将该 html 文本并显示内容;

1.4 http 请求方法

  • GET 向指定的资源发出“显示”请求。使用GET方法应该只用在读取数据,而不应当被用于产生“副作用”的操作中例如在Web Application中。其中一个原因是GET可能会被网络蜘蛛等随意访问。
  • HEAD与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。它的好处在于,使用这个方法可以在不必传输全部内容的情况下,就可以获取其中“关于该资源的信息”(元信息或称元数据)。
  • POST向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。
  • PUT :向指定资源位置上传其最新内容。
  • DELETE:请求服务器删除Request-URI所标识的资源。
  • TRACE:回显服务器收到的请求,主要用于测试或诊断。
  • OPTIONS:这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用'*'来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作。
  • CONNECT:HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接(经由非加密的HTTP代理服务器)。

1.5 http 状态码

所有HTTP响应的第一行都是状态行,依次是当前HTTP版本号,3位数字组成的状态代码,以及描述状态的短语,彼此由空格分隔。

状态代码的第一个数字代表当前响应的类型:

虽然 RFC 2616 中已经推荐了描述状态的短语,例如"200 OK","404 Not Found",但是WEB开发者仍然能够自行决定采用何种短语,用以显示本地化的状态描述或者自定义信息。

1.6 url 

超文本传输协议(HTTP)的统一资源定位符将从因特网获取信息的五个基本元素包括在一个简单的地址中:

  • 传送协议。
  • 层级URL标记符号(为[//],固定不变)
  • 访问资源需要的凭证信息(可省略)
  • 服务器。(通常为域名,有时为IP地址)
  • 端口号。(以数字方式表示,若为HTTP的默认值“:80”可省略)
  • 路径。(以“/”字符区别路径中的每一个目录名称)
  • 查询。(GET模式的窗体参数,以“?”字符为起点,每个参数以“&”隔开,再以“=”分开参数名称与数据,通常以UTF8的URL编码,避开字符冲突的问题)
  • 片段。以“#”字符为起点

以http://www.luffycity.com:80/news/index.html?id=250&page=1 为例, 其中:

http,是协议;
www.luffycity.com,是服务器;
80,是服务器上的网络端口号;
/news/index.html,是路径;
?id=250&page=1,是查询。
大多数网页浏览器不要求用户输入网页中“http://”的部分,因为绝大多数网页内容是超文本传输协议文件。同样,“80”是超文本传输协议文件的常用端口号,因此一般也不必写明。一般来说用户只要键入统一资源定位符的一部分(www.luffycity.com:80/news/index.html?id=250&page=1)就可以了。

1.7 http 请求格式

1.8 http 响应格式

2.web框架

2.1 web框架概述

  • 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演。
  • 对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。

功能:

  • socket收发消息
  • 根据不同路径返回不同的内容
  • 返回动态页面(字符串的替换  - 模板的渲染)

分类:

  • Django
  • flask
  • tornado

1 建立web框架(最简单的web框架)

import socket
server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen()

while 1:
    conn, addr = server.accept()
    from_b_msg = conn.recv(1024).decode('utf-8')
    # print(from_b_msg) #客户端的请求内容
    # 获得请求文件
    path = from_b_msg.split('\r\n')[0].split(' ')[1]
    print(path)
    conn.send(b'HTTP/1.1 200 ok\r\n\r\n')
    # conn.send(b'<h1>hello</h1>')
  
  #发送需要的文件
    if path == '/':
        with open('test.html', 'rb') as f:
            data = f.read()
        conn.send(data)
        conn.close()
    elif path == '/test.css':
        with open('test.css','rb') as f:
            data = f.read()
        conn.send(data)
        conn.close()
    elif path == '/timg.jpg':
        with open('timg.jpg', 'rb') as f:
            data = f.read()
        conn.send(data)
        conn.close()
    elif path == '/test.js':
        with open('test.js', 'rb') as f:
            data = f.read()
        conn.send(data)
        conn.close()
    elif path == '/meinv.ico':
        with open('meinv.ico', 'rb') as f:
            data = f.read()
        conn.send(data)
        conn.close()

2.多线程框架(所需文件放在响应目录下)

from threading import Thread
import socket
server = socket.socket()
# server.bind(('192.168.12.45',8080))
server.bind(('127.0.0.1',8080))
server.listen()

def html(conn):
    with open('test.html', 'rb') as f:
        data = f.read()
    conn.send(data)
    conn.close()
def js(conn):
    with open('test.js', 'rb') as f:
        data = f.read()
    conn.send(data)
    conn.close()
def css(conn):
    with open('test.css', 'rb') as f:
        data = f.read()
    conn.send(data)
    conn.close()
def img(conn):
    with open('timg.jpg', 'rb') as f:
        data = f.read()
    conn.send(data)
    conn.close()
def ico(conn):
    with open('meinv.ico', 'rb') as f:
        data = f.read()
    conn.send(data)
    conn.close()
urlpatterns=[
    ('/',html),
    ('/test.css',css),
    ('/timg.jpg',img),
    ('/test.js',js),
    ('/meinv.ico',ico),
]
while 1:
    conn, addr = server.accept()
    from_b_msg = conn.recv(1024).decode('utf-8')
    print(from_b_msg)
    path = from_b_msg.split('\r\n')[0].split(' ')[1]
    # print(path)
    conn.send(b'HTTP/1.1 200 ok\r\nk1:v1\r\n\r\n')
    # conn.send(b'<h1>hello</h1>')
    for url_func in urlpatterns:
        if url_func[0] == path:
            #多线程函数版
            t = Thread(target=url_func[1],args=(conn,))
            t.start()
            # 简单函数版
            # url_func[1](conn)

3.多个页面切换和动态效果(所需文件放在响应目录下)

  ①python文件 

from threading import Thread
import socket
server = socket.socket()
# server.bind(('192.168.12.45',8080))
server.bind(('127.0.0.1',8080))
server.listen()

import datetime
def base(conn):
    with open('base.html','r',encoding='utf-8') as f:
        data = f.read()
    t1 = datetime.datetime.now()
    new_data = data.replace('@xx@',str(t1))
    conn.send(new_data.encode('utf-8'))
def index(conn):
    with open('index.html', 'rb') as f:
        data = f.read()
    conn.send(data)
def home(conn):
    with open('home.html', 'rb') as f:
        data = f.read()
    conn.send(data)
def articles(conn):
    with open('art.html', 'rb') as f:
        data = f.read()
    conn.send(data)
urlpatterns=[
    ('/',base),
    ('/index',index),
    ('/home',home),
    ('/articles',articles),
]

while 1:
    conn, addr = server.accept()
    from_b_msg = conn.recv(1024).decode('utf-8')
    print(from_b_msg)
    path = from_b_msg.split('\r\n')[0].split(' ')[1]
    # print(path)
    conn.send(b'HTTP/1.1 200 ok\r\nk1:v1\r\n\r\n')
    # conn.send(b'<h1>hello</h1>')
    for url_func in urlpatterns:
        if url_func[0] == path:
            #多线程函数版
            t = Thread(target=url_func[1],args=(conn,))
            t.start()
            # 简单函数版
            # url_func[1](conn)

  ②html文件

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap 101 Template</title>
</head>
<body>
<h1 style="color: purple;">欢迎来到王者荣耀页面</h1>
<a href="http://127.0.0.1:8080/index">这是index</a>
<a href="http://127.0.0.1:8080/home">这是home</a>
<h1 style="color: pink;">@xx@</h1>

</body>
</html>

4.wsgire模块板web框架

from wsgiref.simple_server import make_server
# wsgiref本身就是个web框架,提供了一些固定的功能(请求和响应信息的封装,
不需要我们自己写原生的socket了也不需要咱们自己来完成请求信息的提取了,提取起来很方便)
#函数名字随便起
def application(environ, start_response):
    '''
    :param environ: 是全部加工好的请求信息,加工成了一个字典,通过字典取值的方式就能拿到很多你想要拿到的信息
    :param start_response: 帮你封装响应信息的(响应行和响应头),注意下面的参数
    :return:
    '''
    start_response('200 OK', [('Content-Type', 'text/html'),('k1','v1')])
    # print(environ)
    print('>>>>>',environ['PATH_INFO'])  #输入地址127.0.0.1:8000,
        这个打印的是'/',输入的是127.0.0.1:8000/index,打印结果是'/index'
    return [b'<h1>Hello, web!</h1>']

#和咱们学的socketserver那个模块很像啊
httpd = make_server('127.0.0.1', 8080, application)

print('Serving HTTP on port 8080...')
# 开始监听HTTP请求:
httpd.serve_forever()

最新文章

  1. Linux 基础操作
  2. ArrayList和HashSet的Contains()方法(转)
  3. [转]C/C++ 程序员必须收藏的资源大全
  4. JQuery Easy Ui DataGrid
  5. Linux useful command
  6. BZOJ-1202 狡猾的商人 并查集+前缀和
  7. .net利用本地播放器播放视频文件代码
  8. JS使用百度地图API
  9. 挑战EXT——QUI框架介绍与下载
  10. #Leet Code# Binary Tree Max[待精简]
  11. MySQL被Oracle并购后的409个日日夜夜
  12. java(try块语句变量,和匿名类变量生存时间
  13. OpenGL---------BMP文件格式
  14. ANSI X9.8标准 PIN xor PAN获取PIN BlOCK
  15. Floating IP in OpenStack Neutron
  16. 【20171104中】chrome自动刷新网页
  17. protobuf 安装与卸载
  18. debug调试命令
  19. minio上传大于30M文件失败
  20. centos7安装zookeeper3.4.12集群

热门文章

  1. 【四】jquery之文档处理习题(内部处理、外部处理)[移动节点]
  2. postman(六):详解在Pre-request Script中如何执行请求
  3. 雷林鹏分享:jQuery EasyUI 数据网格 - 创建自定义视图
  4. 数据分析库之Numpy
  5. MVC框架初识
  6. github命令总结
  7. python 爬虫 记录
  8. linux c使用socket进行http 通信,并接收任意大小的http响应(三)
  9. 1093 字符串A+B
  10. python常见错误