HTTP协议
2021-05-05 14:28
标签:ons 等等 通过命令 line 内容 传输层 红点 选择 嵌套 HTTP协议: 模拟简单浏览器进行网络通信: web服务器: web服务器返回固定页面: web服务器-面向对象实现: 协程实现多任务: web服务器-命令行参数控制内部绑定的端口: HTTP协议 标签:ons 等等 通过命令 line 内容 传输层 红点 选择 嵌套 原文地址:https://www.cnblogs.com/huaibin/p/12107300.html"""
http服务器本质也是tcp服务器.
浏览器 --> (通过HTTP协议 格式) HTTP服务器,也可看作是TCP服务器
格式:就是http协议
域名就是一串字符串.域名的本质还是IP.
域名找DNS去解析域名,转换成对应的IP.(类似找电话本的过程,由电话本里面的名字找到对应的电话号码,这里名字就是域名,电话号码就是IP地址)
域名解析:域名转换成IP地址
domain name service
DNS:1.> 建立连接 2.> 发起请求 3.> 回复响应
DHCP:动态主机配置协议 dynamic host configuration protocol .给局域网中的计算机自动分配IP
"""
"""
url:就是网址,分为下面三部分
1.协议部分
2.域名部分
3.资源路径部分 --> 就是用户想要访问的资源在服务器的哪个位置的哪个文件
HTTP协议: 超文本传输协议 就是用来传输网页的数据.制作者:蒂姆.博纳斯.李 为了方便科学家展示研究成果
而开发的协议.就可以实现跨网络的数据传输.
目前使用的就是http/1.1版本
HTTP作用:浏览器-服务器之间传输网页数据资源
HTTP协议:就是tcp协议加上一些格式
网路传输模型:
应用层 http/https ftp/sftp:加了s的就是加密了
传输层 tcp/udp 比较底层了 端口是传输层使用的
网络层 ip 更加底层了
网络接口层 最底层
寄快递--> 应用层 任务/目标
快递公司--> 顺丰 邮政 选择哪一家快递公司提供服务 传输层 选择哪一种传输协议
物流中转站--> 网络层 转发 选择路径 根据目的ip选择路径 转发出去 就是根据目的地址选择走哪条路径 然后发出去
运输工具--> 轮船,飞机,火车,汽车 网络接口层,就看底层 提供了什么工具了 运输过程选择什么工具进行运输
路由器是工作在网络层的/和ip打交道 将数据包根据ip进行转发
交换机是工作在传输层的
HTTP协议的工作模式:一次请求
# 0.创建socket
# 1.输入网址 域名解析 获取服务器ip
# 2.和服务器建立连接
# 3.发送 请求报文
# 4.接收 响应报文
# \r\n记得一定要带,否则会出错
import socket
# 创建socket
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立连接
tcp_socket.connect((‘www.jd.com‘, 80))
# 请求行
request_line = ‘GET / HTTP/1.1\r\n‘
# 请求头
request_header = ‘User-Agent:%s\r\n‘ % (
‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36‘)
# 拼接请求数据
request_data = request_line + request_header + ‘\r\n‘
# 转成bytes字节类型进行发送
tcp_socket.send(request_data.encode())
# 返回服务器回送的数据
response_data = tcp_socket.recv(4096)
# 输出
print(response_data.decode())
"""
流程: Nginx 脑海中建立一条生产线
PWS1.0目的:在用户每次访问的时候,都返回一个固定的数据,例如Hello World
1.>接收请求报文
2.>解析请求报文-得到用户需求
3.>根据用户的需求找到对应的资源
4.>资源打包到HTTP响应报文
5.>发送响应报文给浏览器
最开始肯定是最简单的,一步一步的加多,慢慢地才会出来
PWS1.0:Python Web Server 1.0
"""
import socket
def main():
# 1. 创建tcp服务器的socket 设置选项 绑定 监听
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((‘‘, 8887)) # 这里绑定的是服务器的固定端口,目的是让客户端能连接到了我的机器上面之后,可以找到我的这个程序
server_socket.listen(128)
while True:
# 2.接受用户连接,从这里开始才是需要不断的进行,才使用死循环
client_socket, client_addr = server_socket.accept()
print(‘接受到%s的连接请求‘ % str(client_addr))
# 3.接收用户请求报文
request_data = client_socket.recv(4096)
print(type(request_data)) #
标题加粗的效果
# 响应行 响应头/可以是0个 空行 响应体数据 这四个 只有响应头可以省略,其他的都不可以省略
response_data = ‘HTTP/1.1 200 OK\r\nServer:PWS1.0\r\n\r\n‘ + ‘Hello World
‘
client_socket.send(response_data.encode())
# 5.一次请求/响应 就关闭连接 --> 短连接
client_socket.close()
if __name__ == ‘__main__‘:
main()"""
PWS2.0目的:在用户每次访问的时候,都会返回一个固定的页面,比如index.html
1.>接收请求报文
2.>解析请求报文-得到用户需求
3.>根据用户的需求找到对应的资源
4.>资源打包到HTTP响应报文
最开始肯定是最简单的,一步一步的加多,慢慢地才会出来
PWS2.0:Python Web Server 2.0
"""
import socket
def main():
# 1. 创建tcp服务器的socket 设置选项 绑定 监听
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((‘‘, 8888)) # 这里绑定的是服务器的固定端口,目的是让客户端能连接到了我的机器上面之后,可以找到我的这个程序
server_socket.listen(128)
while True:
# 2.接受用户连接
client_socket, client_addr = server_socket.accept()
print(‘接受到%s的连接请求‘ % str(client_addr))
# 3.接收用户请求报文
request_data = client_socket.recv(4096)
print(request_data)
# 4.返回固定的文件数据作为响应体 打包到响应报文中
with open(‘33.jpg‘, ‘rb‘) as file:
html_data = file.read() # html_data 是二进制bytes字节类型的数据
# .encode()先把前面的str类型转成bytes字节类型,然后拼接
response_data = (‘HTTP/1.1 200 OK\r\nServer:PWS2.0\r\n\r\n‘).encode() + html_data
client_socket.send(response_data)
# 5.一次请求/响应 就关闭连接 --> 短连接
client_socket.close()
if __name__ == ‘__main__‘:
main()
"""
PWS5.0目的:使用协程实现多任务,提高体验
1.>接收请求报文
2.>解析请求报文-得到用户需求
3.>根据用户的需求找到对应的资源
4.>资源打包到HTTP响应报文
最开始肯定是最简单的,一步一步的加多,慢慢地才会出来
PWS2.0:Python Web Server 2.0
主从
master slave
主:接受用户数据
从:干活
leader:
follower:
"""
import socket
import re
import gevent
from gevent import monkey
monkey.patch_all() # 自动切换 time.sleep recv accept 这些类型的函数在执行的时候会出现大量的耗时等待,所以让这部分闲置时间加以利用.
class HTTPServer:
"""web服务"""
def __init__(self):
"""初始化操作"""
# 1. 创建tcp服务器的socket 设置选项 绑定 监听
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((‘‘, 8999)) # 这里绑定的是服务器的固定端口,目的是让客户端能连接到了我的机器上面之后,可以找到我的这个程序
server_socket.listen(128)
# 将socket对象保存在 当前对象的属性中
self.server_socket = server_socket
def start(self):
"""启动服务"""
while True:
client_socket, client_addr = self.server_socket.accept()
print(‘接受到%s的连接请求‘ % str(client_addr))
# 为每个用户创建一个协程,并且启动 运行
gevent.spawn(self.client_handler, client_socket)
def client_handler(self,client_socket):
"""处理每个客户端的请求"""
# 3.接收用户请求报文
request_data = client_socket.recv(4096)
# 解码 bytes --> str
request_data_str = request_data.decode()
print(request_data)
# ps:当用户的请求路径为/时候,表示其请求的是首页homepage
# 解析用户请求 获取到用户的资源请求路径
# 正则匹配 只要是有/ 提取请求路径
# GET /index.html
result = re.search(r‘^\w+ (/\S*)‘, request_data_str)
# 判断是否提取成功 成功就取出这个值,不成功结束程序
if not result: # 路径为空
print(‘请求报文格式错误‘)
client_socket.close()
return # 结束 这种情况
# 尽量扁平结构 不要使用else缩进去,那样的是嵌套结构,这是小技巧
# 获取请求路径 资源路径
"""
PWS5.0目的:使用协程实现多任务,提高体验
1.>接收请求报文
2.>解析请求报文-得到用户需求
3.>根据用户的需求找到对应的资源
4.>资源打包到HTTP响应报文
最开始肯定是最简单的,一步一步的加多,慢慢地才会出来
PWS2.0:Python Web Server 2.0
主从
master slave
主:接受用户数据
从:干活
leader:
follower:
"""
import socket
import re
import gevent
from gevent import monkey
monkey.patch_all() # 自动切换 time.sleep recv accept 这些类型的函数在执行的时候会出现大量的耗时等待,所以让这部分闲置时间加以利用.
def client_handler(client_socket):
"""处理每个客户端的请求"""
# 3.接收用户请求报文
request_data = client_socket.recv(4096)
# 解码 bytes --> str
request_data_str = request_data.decode()
print(request_data)
# ps:当用户的请求路径为/时候,表示其请求的是首页homepage
# 解析用户请求 获取到用户的资源请求路径
# 正则匹配 只要是有/ 提取请求路径
# GET /index.html
result = re.search(r‘^\w+ (/\S*)‘, request_data_str)
# 判断是否提取成功 成功就取出这个值,不成功结束程序
if not result: # 路径为空
print(‘请求报文格式错误‘)
client_socket.close()
return # 结束 这种情况
# 尽量扁平结构 不要使用else缩进去,那样的是嵌套结构,这是小技巧
# 获取请求路径 资源路径
import socket
import re
import gevent
from gevent import monkey
import sys
monkey.patch_all() # 自动切换 time.sleep recv accept 这些类型的函数在执行的时候会出现大量的耗时等待,所以让这部分闲置时间加以利用.
class HTTPServer:
"""web服务"""
def __init__(self, port):
"""初始化操作"""
# 1. 创建tcp服务器的socket 设置选项 绑定 监听
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((‘‘, port)) # 这里绑定的是服务器的固定端口,目的是让客户端能连接到了我的机器上面之后,可以找到我的这个程序
server_socket.listen(128)
# 将socket对象保存在 当前对象的属性中
self.server_socket = server_socket
def start(self):
"""启动服务"""
while True:
client_socket, client_addr = self.server_socket.accept()
print(‘接受到%s的连接请求‘ % str(client_addr))
# 为每个用户创建一个协程,并且启动 运行
gevent.spawn(self.client_handler, client_socket)
def client_handler(self, client_socket):
"""处理每个客户端的请求"""
# 3.接收用户请求报文
request_data = client_socket.recv(4096)
# 解码 bytes --> str
request_data_str = request_data.decode()
print(request_data)
# ps:当用户的请求路径为/时候,表示其请求的是首页 homepage
# 解析用户请求 获取到用户的资源请求路径
# 正则匹配 只要是有/ 提取请求路径
# GET /index.html
result = re.search(r‘^\w+(/\S*)‘, request_data_str)
# 判断是否提取成功 成功就取出这个值,不成功结束程序
if not result: # 路径为空
print(‘请求报文格式错误‘)
client_socket.close()
return # 结束 这种情况
# 尽量扁平结构 不要使用else缩进去,那样的是嵌套结构,这是小技巧
# 获取请求路径 资源路径