11.17
今日内容
1.黏包现象
2.struct模块
3.黏包代码实战
4.UDP协议(了解)
5.并发编程理论
6.多道技术
7.进程理论
8.进程的并行与并发
9.进程的三状态
1.黏包现象
服务端一次性接收到了客户端三次的消息,该现象称为黏包现象
黏包现象产生的原因
1.不知道每次的数据到底多大
2.TCP也称为流式协议:数据像水流一样绵绵不绝没有间隔(TCP会针对数据量较小且发送间隔较短的多条数据一次性合并打包发送)
避免黏包现象的核心思路:如何确定接收的数据具体有多大
2.struct模块
import struct
data_dict = {
'file_name': 'xxx老师教学.avi',
'file_size': 123132131232342342423423423423432423432,
'file_info': '内容精彩 不要错过',
'file_desc': '名家大作 私人珍藏'
}
import json
data_json = json.dumps(data_dict)
print(len(data_json.encode('utf8'))) # 真实字典的长度 228
res = struct.pack('i', len(data_json.encode('utf8')))
print(len(res))
黏包问题解决方案
客户端
1.制作真实数据的信息字典(数据长度、数据简介、数据名称)
2.利用struct模块制作字典的报头
3.发送固定长度的报头(解析出来是字典的长度)
4.发送字典数据
5.发送真实数据
服务端
1.接收固定长度的字典报头
2.解析出字典的长度并接收
3.通过字典获取到真实数据的各项信息
4.接收真实数据长度
3.黏包代码实战
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))
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)
4.UDP协议(了解)
1.UDP服务端和客户端'各自玩各自的'
2.UDP不会出现多个消息发送合并
5.并发编程理论
计算机中真正干活的是CPU
操作系统发展史
1.穿孔卡片阶段
计算机很庞大,使用很麻烦,一次只能给一个人使用,期间很多时候计算机都不工作
好处:独占计算机,比较自由,不用排队
坏处:计算机利用率太低,浪费资源
2.联机批处理系统
提前使用磁带一次性录入多个程序员编写的程序,然后交给计算机执行
CPU工作效率有所提升,不用反复等待程序录入
3.脱机批处理系统
提升了CPU的利用率
6.多道技术
单道技术:所有的程序排队执行,过程中不能重合
多道技术:利用空闲时间提前准备其他数据,最大化提升CPU利用率
多道技术详细
切换:计算机的CPU在两种情况下会切换,切换给其他人用
1.程序有IO操作
输入\输出操作
input、time.sleep、read、write
2.程序长时间占用CPU,比较浪费,我们得让多个程序都能被CPU运行一下
保存状态
CPU每次切换走之前都需要保存当前操作的状态,下次切换回来基于上次的进度继续执行
7.进程理论
进程与程序的区别
程序:没有被运行起来的一堆死代码
进程:正在运行的程序
进程的调度算法(重要)
1.FCFS,先来先服务,对短作业不友好
2.短作业优先调度,对长作业不友好
3.时间片轮转法+多级反馈队列(目前还在用)
将时间均分,然后根据进程时间长短分为多个等级,等级越靠下表示耗时越长,每次分到的时间越多,但是优先级越低
8.进程的并行与并发
并行:多个进程同时执行,必须要有多个CPU参与,单个CPU无法实现并行
并发:多个进程看上去像同时执行,单个CPU可以实现,多个CPU也可以
判断下列两句话孰对孰错
我写的程序很牛逼,运行起来之后可以实现14个亿的并行量
不合理,并行量必须要有对等的CPU才可以实现,不可能有那么多CPU
我写的程序很牛逼,运行起来之后可以实现14个亿的并发量
合情合理,完全可以实现,以后我们的项目一般都会追求高并发
9.进程的三状态
就绪态:所有的进程在被CPU执行之前都必须先进入就绪态等待
运行态:CPU正在执行
阻塞态:进程运行过程中出现了IO操作 阻塞态无法直接进入运行态 需要先进入就绪态
浙公网安备 33010602011771号