Flask框架小程序后端分离开发学习笔记《3》客户端向服务器端发送请求

Flask框架小程序后端分离开发学习笔记《3》客户端向服务器端发送请求

Flask是使用python的后端,由于小程序需要后端开发,遂学习一下后端开发。

一、为什么请求数据需要先编码

#构造一个HTTP请求
http_request = 'GET / HTTP/1.1\r\nhost:{}\r\n\r\n'.format(host)#发送HTTP请求给服务器
#send函数只接受bytes 作为参数
# str.encode把str转换为bytes,编码是utf-8
request = http_request.encode('utf-8')

可以看到上述代码构建了一个HTTP请求,在发送之前需要将发送之前,使用http_request.encode(‘utf-8’)。
这是因为我们在这构建的请求是字符串文本,而电脑只认识二进制0和1,所以需要将其数据类型转换为二进制类型。

这里的utf-8是一种编码规则,utf-8就像小学学习的字典一样,给每个字符都定义了一个对应的二进制的值代表它。
例如:在UTF-8编码中,字符"G"(大写字母G)用二进制表示是 01000111。

当然编码规则有非常多,除此之外常见的还有ASCII编码、UNICODE编码、GBK等。

二、如何recv所有数据

# recv 可以接收客户端发送过来的数据
# 参数是要接收的字节数
# 返回值是一个bytes类型(随便写的,1024是长度,只接收客户端发送的1024字节,我们之后可以用while持续接收)
request = connection.recv(1024)

上述代码中的1024是接收请求的字节长度,即,一个请求发送过来,我只接收1024字节长度的数据。如果只有这样的话,我们只能接收到前1024字节的长度,如果数据长度大于此,后面的数据就没接收到。

有些朋友就说,那我把这个长度设置的很大很大就得了。理论上,recv 函数的这个参数确实可以设置为任何正整数值。
但是,实际上接收的数据量取决于几个因素,包括网络条件、套接字类型和对方发送数据的方式。在实际应用中,常见的做法是设置这个值为 4096 或 8192,这通常足以处理大多数情况下的数据传输需求。但如果需要,这个值可以被设置得更大,比如 65536(64KB)或更高。

重要的是要了解,recv 函数读取的是缓冲区中的数据,因此设置的值应该与您预期的数据量和缓冲区大小相匹配。设置过大的值不会导致错误,但可能会导致不必要的内存占用。同时,接收的数据可能会少于请求的字节数,这并不是异常,而是正常现象,因为TCP套接字可能会分多次接收完整的数据。

在代码中,我们可以通过循环的方式,分多次接收完整的数据,如下:

# recv 可以接收客户端发送过来的数据buffer_size = 1000r = b''while True:request = connection.recv(buffer_size)r += request# 取到的数据长度不够recv的参数的时候,说明数据己经取完了if len(request) < buffer_size:break

有些朋友就会产生疑惑,request = connection.recv(buffer_size)会从上一次没接收完的断点继续接收数据吗?还是一直都重复接收数据的前buffer_size 字节数据呢?
答:
在网络编程中,当你使用像 recv(buffer_size) 这样的方法从一个网络连接接收数据时,它会按照你指定的缓冲区大小(在这个例子中是 buffer_size)接收数据。如果数据流中还有更多数据,但不足以填满整个缓冲区,recv 将会返回当前可用的数据,并且下一次调用 recv 时会继续从上次停止的地方接收数据

三、http头

当构建好http服务器时,使用浏览器输入域名和端口访问时,服务器端会发现有两次请求过来。如下在代码旁注释功能。

D:\python3.10.7\python.exe E:\flask_learn\http1.py 
ip and request,('127.0.0.1', 52625)
GET / HTTP/1.1				请求方式与协议   /路径是默认路径 
Host: localhost:2000     主机号,一定要有,不然找不到谁发送的,给不了回复
Connection: keep-alive   TCP保持连接,不用一直重复连接-断开。(还有个属性是close,即关闭)
sec-ch-ua: "Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0    
User-Agent重要字段,伪装浏览器信息,避免不兼容
Accept: 浏览器接收什么类型的数据text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br   可以接受的编码方式
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6  
希望可以接收的语言,中英之类ip and request,('127.0.0.1', 52626)
GET /favicon.ico HTTP/1.1     第二次的这个路径不一样了,
Host: localhost:2000
Connection: keep-alive
sec-ch-ua: "Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0
sec-ch-ua-platform: "Windows"
Accept: image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: image
Referer: http://localhost:2000/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6

第二次请求,是请求的图标,如下
在这里插入图片描述

代码示例:客户端向服务器端发送请求

# 构建一个简单本地http服务器
import socket
# 这个程序就是一个套路程序,套路程序
# 没必要思考为什么会龙区年#记住套路,能用,就够了
# 运行这个程序后,浏览器打开localhost:2000就能访问了;localhost是本机域名,本机ip:127.0.0.1# 服务器的host为空字符串,表示接受任意ip地址的连接
# post是端口,这里设置为2000,随便选的一个数字(尽量1024以上,以下是操作系统保留的端口)
host = ''
port = 2000#s是—个socket实例
s = socket.socket()
#s.bind用于绑定(因为服务器有一个固定的端口,所以需要绑定host和port)
#注意bind 函数的参数是一个tuple
s.bind((host, port))#用一个无限循环采处理请求
while True:# 套路,先要s.listen开始监听# 注意参数5的含义不必关心s.listen(5)# 当有客户端过来连接的时候,s.accept函数就会返回2个值# 分别是 连接 和 客户端ip 地址# 其实程序是在这等着接收连接呢connection, address = s.accept()# recv 可以接收客户端发送过来的数据# 参数是要接收的字节数# 返回值是一个bytes类型(随便写的,1024是长度,只接收客户端发送的1024字节,我们之后可以用while持续接收)buffer_size = 1000r = b''while True:request = connection.recv(buffer_size)r += request# 取到的数据长度不够recv的参数的时候,说明数据己经取完了if len(request) < buffer_size:break# bytes类型调用decode ( ' utf-8 ')来转成一个字符串( str)print('ip and request,{}\n{}'.format(address, request.decode('utf-8')))# b''表示这是一个bytes 对象response = b'HTTP/1.1 200 hao\r\n\r\n<h1>Hello world!</h1>'# 用sendall发送给客户端connection.sendall(response)# 发送完毕后,关闭本次连接connection.close()
#codinq: utf-8
# 构造一个请求,发送给自己本机上一个代码构建的服务器import socket
# socket 是操作系统用来进行网络通信的底层方案#简而言之,就是发送/接收数据
#创建一个socket对象
#参数socket.AF_INET表示是ipv4协议]#参数socket. sOCK_STREAM表示是tcp协议
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#这两个其实是默认值,所以你可以不写,如下
#s = socket.socket()    socket只能用于http协议的,不能用于https
#s = ssl. wrap_socket ( socket.socket ( ) )   这个用于https#主机(域名或者ip)和端口
host = 'localhost'
port = 2000
#用connect函数连接上主机,参数是一个tuple
s.connect( (host,port) )#连接上后,可以通过这个函数得到本机的ip和端口(本地ip路由器分配得到,本地端口操作系统分配的)
ip, port = s.getsockname()
print('本机ip 和port {}\{}'.format(ip, port))#构造一个HTTP请求
http_request = 'GET / HTTP/1.1\r\nhost:{}\r\n\r\n'.format(host)#发送HTTP请求给服务器
#send函数只接受bytes 作为参数
# str.encode把str转换为bytes,编码是utf-8
request = http_request.encode('utf-8')
print('请求',request)
s.send(request)# 接受服务器的响应数据
#参数是长度,这里为1023字节
#所以这里如果服务器返回的数据中超过1023的部分你就得不到了,正经一次性最长大概1500字节,
response = s.recv (1023)
#输出响应的数据,bytes类型
print('响应',response)
#转成str再输出
print('响应的str 格式',response.decode ('utf-8'))

运行结果:
发送请求的客户端运行结果:
客户端
服务器端:
在这里插入图片描述
可以看到我运行了两次发送请求的程序,操作系统分配给其程序的两次端口不一样。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/639342.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大语言模型系列-ELMo

文章目录 前言一、ELMo的网络结构和流程二、ELMo的创新点总结 前言 在前文大语言模型系列-word2vec已经提到word2vec的缺点&#xff1a; 为每个词汇表中每个分词静态生成一个对应的词向量表示&#xff0c;没有考虑到语境&#xff0c;因此无法无法处理多义词 ps&#xff1a;先…

Python Web 开发之 Flask 入门实践

导语&#xff1a;Flask 是一个轻量级的 Python Web 框架&#xff0c;广受开发者喜爱。本文将带领大家了解 Flask 的基本概念、搭建一个简单的 Web 项目以及如何进一步扩展功能。 一、Flask 简介 Flask 是一个基于 Werkzeug 和 Jinja2 的微型 Web 框架&#xff0c;它的特点是轻…

JAVA RPC Thrift基操实现与微服务间调用

一、Thrift 基操实现 1.1 thrift文件 namespace java com.zn.opit.thrift.helloworldservice HelloWorldService {string sayHello(1:string username) }1.2 执行命令生成Java文件 thrift -r --gen java helloworld.thrift生成代码HelloWorldService接口如下 /*** Autogene…

MBR扇区修复和GRUB引导修复实验

修复MBR扇区 步骤一&#xff1a;在进行实验之前我们需要新加一块磁盘&#xff0c;并对新加磁盘进行分区处理&#xff0c;用来备份sda磁盘的MBR及分区表信息。&#xff08;注&#xff1a;在实验中可以不像我如此这么繁琐&#xff0c;一个主分区&#xff0c;并格式化挂载即可&am…

Android 通过adb命令查看应用流量

一. 获取应用pid号 通过adb shell ps | grep 包名 来获取app的 pid号 二. 查看应用流量情况 使用adb shell cat /proc/#pid#/net/dev 命令 来获取流量数据 备注&#xff1a; Recevice: 表示收包 Transmit: 表示发包 bytes: 表示收发的字节数 packets: 表示收发正确的包量…

【GitHub项目推荐--不错的 C 开源项目】【转载】

大学时接触的第一门语言就是 C语言&#xff0c;虽然距 C语言创立已过了40多年&#xff0c;但其经典性和可移植性任然是当今众多高级语言中不可忽视的&#xff0c;想要学好其他的高级语言&#xff0c;最好是先从掌握 C语言入手。 今天老逛盘点 GitHub 上不错的 C语言 开源项目&…

【代码随想录11】239. 滑动窗口最大值 347. 前 K 个高频元素

目录 239. 滑动窗口最大值题目描述做题思路参考代码 347. 前 K 个高频元素题目描述参考代码 239. 滑动窗口最大值 题目描述 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每…

详解C语言中`||`的短路机制

在C语言中&#xff0c;逻辑或运算符&#xff08;||&#xff09;是一种常用的逻辑运算符&#xff0c;用于组合多个条件表达式。与其他编程语言一样&#xff0c;C语言中的逻辑或运算符具有短路机制&#xff0c;这是一种非常重要的概念&#xff0c;本文将深入解释C语言中的||短路机…

MSVS C# Matlab的混合编程系列2 - 构建一个复杂(含多个M文件)的动态库:

前言: 本节我们尝试将一个有很多函数和文件的Matlab算法文件集成到C#的项目里面。 本文缩语: MT = Matlab 问题提出: 1 我们有一个比较复杂的Matlab文件: 这个MATLAB的算法,写了很多的算法函数在其他的M文件里面,这样,前面博客的方法就不够用了。会报错: 解决办法如下…

华为机考入门python3--(0)模拟题2-vowel元音字母翻译

分类&#xff1a;字符串 知识点&#xff1a; 字符串转list&#xff0c;每个字符成为list中的一个元素 list(string) 字符串变大小写 str.upper(), str.lower() 题目来自【华为招聘模拟考试】 # If you need to import additional packages or classes, please import …

分享5款简单实用的软件,值得收藏

​ 电脑上的各类软件有很多&#xff0c;除了那些常见的大众化软件&#xff0c;还有很多不为人知的小众软件&#xff0c;专注于实用功能&#xff0c;简洁干净、功能强悍。 1.自定义图标——TileIconifier ​ TileIconifier 是一款可以自定义 Windows 开始菜单图标的软件&#…

蓝牙运动耳机什么牌子的好?2024年运动无线耳机推荐

​在选择运动耳机时&#xff0c;我们需要综合考虑音质、舒适度以及适应不同运动场景的能力。好的运动耳机能够提高运动效率&#xff0c;增添锻炼的乐趣。今天&#xff0c;我为大家介绍几款在音质、佩戴舒适度、防水防汗等方面表现卓越的运动耳机&#xff0c;助你选购最适合的一…

04 单链表

目录 链表的概念和结构单链表OJ练习 1. 链表的概念和结构 1.1 链表的概念 链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的 1.从上图可以看出链式结构在逻辑上是连续的&#xff0c;物理上不一定连续 2.现…

Docker(十)Docker Compose

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; Docker Compose 项目 Docker Compose 是 Docker 官方编排&#xff08;Orchestration&#xff09;项目之一&#xff0c;负责快速的部署分布式…

Vue diff原理

✨ 专栏介绍 在当今Web开发领域中&#xff0c;构建交互性强、可复用且易于维护的用户界面是至关重要的。而Vue.js作为一款现代化且流行的JavaScript框架&#xff0c;正是为了满足这些需求而诞生。它采用了MVVM架构模式&#xff0c;并通过数据驱动和组件化的方式&#xff0c;使…

Golang leetcode28 找出字符串中第一个匹配项的下标 KMP算法详解

文章目录 找出字符串中第一个匹配项的下标 leetcode28 串的模式匹配问题暴力求解使用KMP模式匹配算法KMP算法简述 KMP算法的代码实现 找出字符串中第一个匹配项的下标 leetcode28 串的模式匹配问题 暴力求解 func strStr(haystack string, needle string) int { L : len(need…

wayland(wl_shell) + egl + opengles 最简实例

文章目录 前言一、ubuntu 上相关环境准备1. ubuntu 上安装 weston2. 确定ubuntu 上安装的opengles 版本3. 确定安装的 weston 是否支持 wl_shell 接口二、窗口管理器接口 wl_shell 介绍二、代码实例1.egl_wayland_demo.c2. 编译和运行2.1 编译2.2 运行总结参考资料前言 本文主…

UE5 C++学习笔记 FString FName FText相互转换

1.FString 是UE里的String。最接近std::string, 唯一可以修改的字符串类型。性能更低 TEXT(string) TEXT宏&#xff0c;作用是将字符串转换成Unicode&#xff0c;切记UE中使用字符串输出要使用该宏 2. FName 是UE里特有的类型。它更注重于表示名称不区分大小写&#xff0c;不…

基于taro搭建小程序多项目框架,记重点了!!!

前言 为什么需要这样一个框架&#xff0c;以及这个框架带来的好处是什么&#xff1f; 从字面意思上理解&#xff1a;该框架可以用来同时管理多个小程序&#xff0c;并且可以抽离公用组件或业务逻辑供各个小程序使用。当你工作中面临这种同时维护多个小程序的业务场景时&#…

web架构师编辑器内容-完成属性设置的优化

对于业务组件来说&#xff0c;其属性是有很多的&#xff0c;如果把所有属性都平铺在页面上&#xff0c;就会非常长&#xff0c;而且想要更改其中的某些属性&#xff0c;可能需要向下滚动很久才能找到&#xff0c;对于UI的交互不是很友好&#xff0c;需要对属性的不同特性进行分…