粘包、struct模块、进程并行与并发
粘包现象
1.服务端连续执行三次recv
2.客户端连续执行三次send
问题:服务端一次性接收到了客户端三次的消息 该现象称为 粘包现象
粘包现象产生的原因:
1.不知道每次的数据到底有多大
2.TCP也称为流式协议:数据像流水一样绵绵不绝没有间隔(TCP会针对数据量较小且发送间隔较短的多条数据一次性打包发送)
注意:只有TCP有粘包现象,UDP永远不会粘包
避免粘包现象的核心思路\关键点:
如何明确即将接收的数据具体有多大
PS:如何将长度变化的数据全部制作成固定长度的数据
struct模块
该模块可以把一个类型 如数字 转成固定长度的bytes
import struct
msg = b'hello jason brother'
print(len(msg)) # 真实长度19
res = struct.pack('i', len(msg)) # 将数据打包成固定的长度 i是固定打包长度
print(res)
print(len(res)) # 打包后长度为(bytes) 4 报头
real_len = struct.unpack('i', res)
print(real_len) # (19,)元组的形式 根据固定长度解析出真实数据的长度
desc = b'what is wrong with you'
print(len(desc)) # 数据真实的长度(bytes) 22
res1 = struct.pack('i', len(desc))
print(len(res1)) # 打包之后长度为(bytes) 4 报头
real_len1 = struct.unpack('i', res1)
print(real_len1) # (22,) 根据固定长度的报头 解析出真实数据的长度
借助struct模块 知道长度数字可以被转换成一个标准大小的4字节数字 利用这个特点预先发送数据长度
发送时 | 接收时 |
---|---|
先发送struct转换好的数据长度4字节 | 先接受4个字节使用struct转换成数字来获取要接受的数据长度 |
再发送数据 | 再按照长度接收数据 |
还可以把报头做成字典 字典里包含将要发送的真实数据的详细信息 然后json序列化 然后struct将序列化后的数据长度打包成4个字节
发送时 | 接收时 |
---|---|
先发报头长度 | 先收报头长度 用struct取出来 |
再编码报头内容然后发送 | 根据取出的长度收取报头内容 然后解码 反序列化 |
最后发真实内容 | 从反序列化的结果中取出待取数据的详细信息 然后去取真实的数据内容 |
解决粘包问题初次版本 |
客户端
1.将真实数据转成bytes类型并计算长度
2.利用struct,模块将真实长度制作一个固定长度的报头
3.将固定长度的报头先发送给服务端 服务端只需要在recv括号内填写固定的长度的报头数据即可
4.然后再发送真实的数据
服务端
1.服务端先接受固定长度的报头
2.利用struct模块反向解析出真实数据长度
3.recv接收真实数据长度即可
问题1:struct模块无法打开数据量较大的数据 就算换更大的模式也不行
res = struct.pack('i', 12313213123)
print(res) # 报错超范围struct.error: argument out of range
struct.error: 'i' format requires -2147483648 <= number <= 2147483647 # 这个是范围
问题2:报头能否传递更多的信息 比如电影大小 电影名称 电影评价电影简介
终极解决方案:字典作为报头打包 效果更好 数字更小
import struct
data_dict = {
'name': 'jason老师教学视频集合',
'size': 131414141423342523543566,
'reaL-info': '手把手教你学 千万不要错过',
'desc': '经典教学视屏'
}
import json
data_json = json.dumps(data_dict)
rang = len(data_json.encode('utf8'))
print(rang) # 237
res = struct.pack('i', rang)
print(len(res)) # 4
粘包问题终极解决方案
客户端
1.制作真实数据的信息字典(数据长度、数据简介、数据名称)
2.利用sturct模块制作字典的报头
3.发送固定长度的报头(解析出来的是字典的长度)
4.发送字典数据
5.发送真实数据
服务端
1.接收固定长度的字典报头
2.解析出字典的长度并接收
3.通过字典获取真实数据的各项消息
4.接收真实数据长度
粘包代码实战
import socket
import struct
import json
server = socket.socket()
server.bind(('127.0.0.1', 8081))
server.listen(5)
sock, addr = server.accept()
# 1.接收固定长度的字典报头
data_dict_head = sock.recv(4)
# 2.根据报头解析出字典数据的长度
data_dict_len = struct.unpack('i', data_dict_head)[0]
# 3.接收字典数据
data_dict_bytes = sock.recv(data_dict_len)
data_dict = json.loads(data_dict_bytes) # 自动解码再反序列化
# 4.获取真实数据的各项信息
# total_size = data_dict.get('file_size')
# with open(data_dict.get('file_name'), 'wb') as f:
# f.write(sock.recv(total_size))
'''接收真实数据的时候 如果数据量非常大 recv括号内直接填写该数据量 不太合适 我们可以每次接收一点点 反正知道总长度'''
# total_size = data_dict.get('file_size')
# recv_size = 0
# with open(data_dict.get('file_name'), 'wb') as f:
# while recv_size < total_size:
# data = sock.recv(1024)
# f.write(data)
# recv_size += len(data)
# print(recv_size)
import socket
import os
import struct
import json
client = socket.socket()
client.connect(('127.0.0.1', 8081))
'''任何文件都是下列思路 图片 视频 文本 ...'''
# 1.获取真实数据大小
file_size = os.path.getsize(r'/Users/jiboyuan/PycharmProjects/day36/xx老师合集.txt')
# 2.制作真实数据的字典数据
data_dict = {
'file_name': '有你好看.txt',
'file_size': file_size,
'file_desc': '内容很长 准备好吃喝 我觉得营养快线挺好喝',
'file_info': '这是我的私人珍藏'
}
# 3.制作字典报头
data_dict_bytes = json.dumps(data_dict).encode('utf8')
data_dict_len = struct.pack('i', len(data_dict_bytes))
# 4.发送字典报头
client.send(data_dict_len) # 报头本身也是bytes类型 我们在看的时候用len长度是4
# 5.发送字典
client.send(data_dict_bytes)
# 6.最后发送真实数据
with open(r'/Users/jiboyuan/PycharmProjects/day36/xx老师合集.txt', 'rb') as f:
for line in f: # 一行行发送 和直接一起发效果一样 因为TCP流式协议的特性
client.send(line)
import time
time.sleep(10)
udp协议(了解)
1.UDP服务端和客户端 各自玩各自的
2.UDP不会出现多个消息发送合并
并发编程理论
研究网络编程其实就是在研究计算机的底层原理及发展史
计算机中真正干活的是CPU
操作系统发展史
1.穿孔卡阶段
计算机很庞大 使用很麻烦 一次只能给一个人使用期间很多时候计算机都不工作
好处:程序员独占计算机 为所欲为
坏处:计算机利用率太低 浪费资源
2.联机批处理系统
提前使用磁带一次性录入多个程序员编写的程序 然后交给计算机执行
CPU工作效率有所提升 不用反复等待程序录入
3.脱机批处理系统
极大提升了CPU的利用率
总结:CUP提升利用率的过程
多道技术
在学习并发编程的过程中 不做刻意的提醒的情况下 默认一台计算机就一个CPU(只有一个干活的人)
单道技术
所有的程序排队执行 过程中不能重合
多道技术
利用空闲时间提前准备其他数量 最大化提升CPU利用率
多道技术详细
1.切换
计算机的CPU在两种情况下会切换(不让你用 给别人用)
1.程序有IO操作 输入\输出操作 input 、time.sleep、read、write
2.程序运行长时间占用CUP 我们得雨露均沾 让多个程序都能被CPU运行一下
2.保存状态
CPU每次切换走之前都需要保存当前操作的状态 下次切换回来的时候基于上次的进度继续执行
'''
就好比开了一家饭店 只有一个服务员 但是同时来了五桌客人
如何让五桌客人都感受到服务员在在服务他们
让服务化身为闪电侠 只要客人有停顿 就立刻切换到其他桌 如此往复
'''
进程理论
进程与程序的区别
程序:一堆死代码(还没有被运行起来)
进程:正在运行的程序(被运行起来了)
进程的调度算法(重要)
1.FCFS(先来先服务) 对短作业不友好
2.短作业优先调度 对长作业不友好
3.时间片轮转法+多级反馈队列(目前还在用)
将时间均分 然后根据进程时间长短再分多个等级
等级越靠下表示耗时越长 每次分到的时间越多 但是优先级越低
进程并行与并发
并行:多个进程同时执行 必须要有多个参与 单个CPU无法实现
并发:多个进程看上去像同时执行 单个CPU可以实现 多个CPU肯定也可以实现
判断下列两句话孰对孰错
我写的代码很牛逼 运行起来之后可以实现14个亿的并行量 肯定错的
并行量必须要有对等的CPU才可以实现
我写的程序很牛逼 运行起来之后可以实现14个亿的并发量 对的
合情合理 完全可以实现 以后我们的项目一般都会追求高并发
PS:目前国内可以说是最牛逼的>>>12306
进程的三状态
就绪状态:
所有的进程在被CPU执行之前都必须先进入就绪态等待
运行状态:
CPU正在执行
阻塞态:
进程运行过程中出现了IO操作 阻塞无法直接进入运行态 需要先进入就绪态
粘包、struct模块、进程并行与并发的更多相关文章
- Learn day9 粘包\struct用法\hashlib校验\socketserver并发\模块引入\进程\join\守护进程
1.粘包现象 总结 : 导致黏包现象的两种情况 hello,worl d (1) 在发送端,发送数据太快,频繁发送 (2) 在接收端,接收数据太慢,延迟截取 # ### 服务端 import sock ...
- python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)
python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程 并行与并发 同步与异步 阻塞与非阻塞 CPU密集型与IO密集型 线程与进程 进 ...
- 黏包-黏包的成因、解决方式及struct模块初识、文件的上传和下载
黏包: 同时执行多条命令之后,得到的结果很可能只有一部分,在执行其他命令的时候又接收到之前执行的另外一部分结果,这种显现就是黏包. 只有TCP协议中才会产生黏包,UDP协议中不会有黏包(udp协议中数 ...
- 通过开启子进程的方式实现套接字服务端可以并发的处理多个链接以及通讯循环(用到了subprocess模块,解决粘包问题)
今日作业:通过开启子进程的方式实现套接字服务端可以并发的处理多个链接以及通讯循环(用到了subprocess模块,解决粘包问题) server(服务端) import socket from mult ...
- Python网络编程(2)-粘包现象及socketserver模块实现TCP并发
1. 基于Tcp的远程调用命令实现 很多人应该都使用过Xshell工具,这是一个远程连接工具,通过上面的知识,就可以模拟出Xshell远程连接服务器并调用命令的功能. Tcp服务端代码如下: impo ...
- 解决socket粘包的两种low版模式 os.popen()和struct模块
os.popen()模式 server端 import socket import os phone = socket.socket() # 实例化一个socket对象 phone.bind((&qu ...
- Py-解决粘包现象,tcp实现并发,tcp实现传输文件的程序,校验思路,线程与进程
黏包现象 TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包,从接收缓冲区来看,后一包数据的头紧接着前一包数据的尾,出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方TCP接收到 ...
- 2、粘包现象(struct模块)
昨天我们所做的套接字是有漏洞的,它会出现粘包现象,没有发现这个问题的我们今天会进行演示.今天也会稍微讲解一下基于udp的套接字. 一.基于udp的套接字 udp是无链接的,先启动哪一端都不会报错 ud ...
- 29、粘包现象(struct模块)
昨天我们所做的套接字是有漏洞的,它会出现粘包现象,没有发现这个问题的我们今天会进行演示.今天也会稍微讲解一下基于udp的套接字. 本篇导航: 基于udp的套接字 粘包现象 粘包 解决粘包方法 stru ...
- {Python之进程} 背景知识 什么是进程 进程调度 并发与并行 同步\异步\阻塞\非阻塞 进程的创建与结束 multiprocess模块 进程池和mutiprocess.Poll
Python之进程 进程 本节目录 一 背景知识 二 什么是进程 三 进程调度 四 并发与并行 五 同步\异步\阻塞\非阻塞 六 进程的创建与结束 七 multiprocess模块 八 进程池和mut ...
随机推荐
- 前端ES6 面试过关宝典
ES6 部分 Typescript 部分 前端工程面经(节流防抖.https.前端攻击.性能优化...) https://juejin.cn/post/6844903734464495623 ES6面 ...
- 1_JavaWeb引言
JavaEE平台 (Java Platform Enterprise Edition) Web进阶核心知识 part1: 数据库应用与JDBC MySQL, SQL语言, JDBC, 三层架构, 连接 ...
- 5_项目实战MyShop
一. 网上商城 1.1 商城类别 B2B 商家对商家 B2C 商家对客户 C2C 客户对客户 O2O 线上线下相结合 1.2 商城常见模块 后台常见功能模块 商品管理 包括后台商品库存管理, 上货, ...
- 阿里云服务器部署Web环境
一.配置阿里云服务器 进入阿里云官方网站(https://www.aliyun.com/). 初次使用的话使用支付宝快速注册账户,并进行个人实名认证. 点击试用中心. 选择第二个,云服务器2核4G. ...
- centos离线安装nvm
PS:因为项目需,客户现场不能联网需要不同的node版本来切换,里面已经内置好了node 8.11.2和12.1.0 两个版本,使用nvm可以切换 链接:https://pan.baidu.com/s ...
- 【原创】推流录屏软件OBS使用教程--录屏
之前有录屏需要,写了一篇关于ffmpeg录屏的文章,反响还不错,但是直接用ffmpeg门槛有些高,今天写一篇图形界面的录屏推流工具OBS的使用教程.这次先写OBS的录屏教程 下载安装 点击 OBS官网 ...
- 《Java并发编程的艺术》读书笔记:一、并发编程的目的与挑战
发现自己有很多读书笔记了,但是一直都是自己闷头背,没有输出,突然想起还有博客圆这么个好平台给我留着位置,可不能荒废了. 此文读的书是<Jvava并发编程的艺术>,方腾飞等著,非常经典的一本 ...
- 二进制安装Dokcer
写在前边 考虑到很多生产环境是内网,不允许外网访问的.恰好我司正是这种场景,写一篇二进制方式安装Docker的教程,用来帮助实施同事解决容器部署的第一个难关. 本文将以二进制安装方式,在CentOS7 ...
- Vitepress搭建组件库文档(上)—— 基本配置
在 vite 出现以前,vuepress 是搭建组件库文档不错的工具,支持以 Markdown 方式编写文档.伴随着 vite 的发展,vitepress 已经到了 1.0.0-alpha.22 版本 ...
- 学习ASP.NET Core Blazor编程系列十——路由(中)
学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...