1.http认识
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是互联网上应用最为广泛的一种网络协议,用于web服务器与浏览器之间传输超文本数据的协议
HTTP是一个基于TCP/IP通信协议来传递数据(HTML网页文件, 图片文件,视频文件, 查询结果等等)
html:(Hyper Text Mark-up Language)超文本标记语言,用html来编写网页
通俗的讲: HTTP是在网络上传输HTML网页的协议,用于浏览器和服务器的通信。
2. HTTP 协议的 Request/Response(请求/响应)模型
3. HTTP 请求报文格式分析
下面就是我们要请求的示例数据:
GET /index.html HTTP/1.1Host: 192.168.192.221:8080Connection: keep-aliveCache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Cookie: BAIDUID=8FD6ED496A03231D920484C6379517CF:FG=1;
1.GET / HTTP/1.1 叫做请求行. 里面包含3个信息, 以空格隔开
2.请求头. 除了第一行之外, 剩下的所有数据的格式都是类似的.叫请求头。
请求报文格式总结
4. HTTP 响应报文格式分析
HTTP/1.1 200 OKConnection: Keep-AliveContent-Encoding: gzipContent-Type: text/html; charset=utf-8Date: Wed, 14 Mar 2018 09:52:48 GMTServer: BWS/1.1
响应数据格式总结
浏览器访问网站的过程
基本流程如下:
- 用户输入网址.
- 浏览器请求DNS服务器, 获取域名对应的IP地址.
- 请求连接该IP地址服务器.
- 发送资源请求. (HTTP协议)
- web服务器接收到请求, 并解析请求, 判断用户意图.
- 获取用户想要的资源.
- 将资源返回给http服务器程序.
- http服务器程序将资源数据通过网络发送给浏览器.
- 浏览器解析呈现请求的数据.
TCP通信的整个过程,如下图:
1. TCP短连接
模拟一种TCP短连接的情况:
- client 向 server 发起连接请求
- server 接到请求,双方建立连接
- client 向 server 发送消息
- server 回应 client
- 一次读写完成,此时双方任何一个都可以发起 close 操作
在步骤5中,一般都是 client 先发起 close 操作。当然也不排除有特殊的情况。
从上面的描述看,短连接一般只会在 client/server 间传递一次读写操作!
2. TCP长连接
再模拟一种长连接的情况:
- client 向 server 发起连接
- server 接到请求,双方建立连接
- client 向 server 发送消息
- server 回应 client
- 一次读写完成,连接不关闭
- 后续读写操作...
- 长时间操作之后client发起关闭请求
3. TCP/IP协议(族)
互联网协议包含了上百种协议标准,但是最重要的两个协议是TCP和IP协议,所以,大家把互联网的协议简称TCP/IP协议(族)
常用的网络协议如下图所示:
- 网络接口层(物理层、数据链路层):包括传输介质(网线)、计算机中对应的网络接口卡等,其实这一层tcp/ip协议是没有定义的,给其上层"网络层"提供访问接口.
- 网络层(互联网层):主要用IP地址来完成对主机的寻址,它还负责数据包在多种网络中的路由
- 运输层:主要为两台主机上的应用提供端到端的通信.
- 应用层:为用户提供所需的服务,比如http服务,ftp服务,smtp服务等.
1. 模拟浏览器访问服务端
import socketdef main(): ???# 1.创建tcp客户端socket对象 ???http_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ???# 2. 连接服务端 ???http_client_socket.connect((‘127.0.0.1‘, 7788)) ???# 3. 发送http请求报文格式 ???""" ????1. 请求行 : GET /index.html HTTP/1.1 ????2. 请求头 : HOST:127.0.0.1:7788 ????3. 分隔符 ??‘\r\n’ ????4. 请求体 ??product_id=1001 ???""" ???request_line = ‘GET /index.html HTTP/1.1\r\n‘ ?# 请求行,必须有 ???request_headers = ‘HOST: 127.0.0.1:7788\r\n‘ ?# 请求头 ???request_headers += ‘Accept: text/html\r\n‘ ???split = "\r\n" ?# 请求头与请求体分隔符 ???request_body = "product_id=1001\r\n" ???request_data = request_line + request_headers + split + request_body ?# 拼接请求报文数据 ???# 发送请求数据到服务端,发送前需编码 ???http_client_socket.send(request_data.encode("utf-8")) ???# 等待接受从服务端应答的消息 ???response_data = http_client_socket.recv(1024) ???print("http服务端应答的数据:", response_data.decode()) ?# 解码输出 ???# 关闭套接字 ???http_client_socket.close()if __name__ == ‘__main__‘: ???main()
2. 简单HTTP服务器实现
1 import socket 2 ?3 ?4 def handle_client(client_socket): 5 ????"""处理浏览器客户端的请求""" 6 ?7 ????# 等待接收客户端发送的消息 8 ????recv_data = client_socket.recv(4096) 9 10 ????# 解码数据11 ????request_data = recv_data.decode("utf-8")12 13 ????# 显示接收到的请求报文数据14 ????print(request_data)15 16 ????# 按照http 响应报文格式去回复客户端17 ????"""http 响应报文格式18 ?????1. 响应行 : HTTP/1.1 200 OK19 ?????2. 响应头 Server: mimiweb1.0 ???Connection: Keep-alive20 ?????3. 分隔符 \r\n21 ?????4. 响应体 ?very good22 ????"""23 ????response_line = "HTTP/1.1 200 OK\r\n" ?# 响应行,必须有24 ????response_headers = "Server: mimiweb1.0\r\n"25 ????response_headers += "Connection: Keep-alive\r\n"26 ????split = "\r\n" ?# 请求头与请求体的分隔符27 ????response_body = "very good\r\n"28 29 ????# 拼接响应报文数据30 ????response_datas = response_line + response_headers + split + response_body31 32 ????# 向客户端发送响应报文数据33 ????client_socket.send(response_datas.encode("utf-8"))34 35 ????# 关闭套接字36 ????client_socket.close()37 38 39 def main():40 ????"""程序主控制入口"""41 42 ????# 创建监听套接字43 ????http_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)44 45 ????# 当套接字四次挥手,可立即复用地址端口46 ????http_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)47 48 ????# 服务端绑定端口49 ????http_server_socket.bind((‘‘, 7788))50 51 ????# 开启监听52 ????http_server_socket.listen(128)53 54 ????# 等待接受浏览器客户端的请求55 ????while True:56 ????????client_socket, client_addr = http_server_socket.accept()57 ????????print("有新的客户端请求,来自>>>", client_addr)58 59 ????????# 在函数中为客户端提供服务60 ????????handle_client(client_socket)61 62 63 if __name__ == ‘__main__‘:64 ????main()
服务器端
客户端
浅谈http协议
原文地址:https://www.cnblogs.com/liuguangbiao/p/9248848.html