TCP.UDP大致回顾
TCP
可靠协议
三次握手建立连接
1. 洪水攻击
2. 消息反馈
四次挥手断开连接
1.time_wait
UDP
不可靠协议
"""
TCP类似于打电话 双方连接
UDP类似于发短信
"""
应用层协议简介
HTTP\HTTPS\FTP...
socket套接字简介
socket套接字作用于应用层于其他层之间 承上启下的类似于操作系统的作用
socket基本使用
import socket
socket.socket() 产生socket对象
bind() 绑定地址
listen() 半连接池
accept() 等待客户端连接
send() 发送消息
recv() 接收消息
connect() 链接服务端
socket代码优化
1.通信循环
2.链接循环
3.发送的消息不能为空、mac电脑反复重启服务端可能会报错地址错误、、服务端利用异常捕获增加健壮性
半连接池概念
listen(5) 只能接收排队5位的意思
缓解服务端与客户端建立连接的压力
黏包现象
1.服务端连续执行三次recv
2.客户端连续执行三次send
问题:服务端一次性接收到了客户端三次的消息 该现象称为"黏包现象"
黏包现象产生的原因
1.不知道每次的数据到底多大
2.TCP也称为流式协议:数据像流水一样绵绵不杜绝没有间隔(TCP会针对数量较小且发送间隔比较短的多条数据一次性合并打包发送)
避免黏包现象的核心思路\关键点
如何明确即将接收的数据具体由多大
ps:如何将长度变化的数据全部制作成固定长度的数据
struct模块
import struct
info = b'hello big baby'
print(len(info)) # 数据真实的长度(bytes) 14
res = struct.pack('i', len(info))
print(len(res)) # 打包之后的长度(bytes) 4报头
real_len = struct.unpack('i', res)
print(real_len) # (14,) genuine固定长度的报头 解释出真实数据的长度
desc = b'hello my baby I will take you to play big ball'
print(len(desc)) # # 数据真实的长度(bytes) 46
res1 = struct.pack('i', len(desc)) # 将desc打包
print(len(res1)) # 打包之后长度为(bytes) 4 报头
real_len1 = struct.unpack('i', res1)
print(real_len1) # (46,) 根据固定长度的报头 解析出真实数据的长度
"""
解决黏包问题初次版本
客户端
1.将真实数据转成bytes类型并计算长度
2.利用struct模块将真实长度制作一个固定长度的报头
3.将固定长度的报头先发送给服务端 服务端只需要在recv括号内填写固定长度的报头数字即可
4.然后再发送真实数据
服务端
1.服务端先接收固定长度的报头
2.利用struct模块反向解析出真实数据的长度
3.recv接收真实数据长度即可
"""
'''问题1:struct模块无法打包数据量较大的数据 就算换更大模块也不行'''
res = struct.pack('i', 1231234123)
print(res)
'''问题2:报头能否传递更多的信息 比如电影大小 电影名称 电影评价 电影简介'''
'''终极解决方案:字典作为报头打包 效果更好 数字更小'''
data_dict = {
'file_name':'xxx老师教学.avi',
'file_size':12312313212121231213,
'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.接收真实数据长度
"""
黏包代码实战
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')
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'D:\python代码\网络编程\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'D:\python代码\网络编程\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的利用率
总结:CPU提升利用率的过程
多道技术
"""
在学习并发编程的过程中 不做刻意提醒的情况下 默认一台计算机就一个CPU(只有一个干活的人)
"""
单道技术
所有的程序排队执行 过程中不能重合
多道技术
利用空闲时间提前准备其他数据 最大化利用CPU 提升使用率
多道技术详细
1.切换
计算机的CPU在两种情况下会切换(不让你用 给别人用)
1.程序有IO操作
输入\输出操作
input、time。sleep、read、write
2.程序长时间占用CPU
我们得雨露均沾 让多个程序都能被CPU运行一下
2.保存状态
CPU每次切换走之前都需要保存当前操作得状态 下次切换回来基于上次得进度继续执行
"""
开了一家饭店 只有一个服务员 但是同时来了五桌客人
请问:如何让五桌客人都感觉到服务员在服务他们
让服务员化身闪电侠 只要有客户停顿 就可以切换到其他桌 如此往复
"""
进程理论
进程与程序的区别
程序:一堆死代码(还没有运行起来)
进程:正在运行的程序(被运行起来了)
进程的调度算法(重要)
1.FCFS(先来先服务)
对短作业不友好
2.短作业优先调度
对长作业不友好
3.时间片轮转法+多级反馈队列(目前还在用)
将时间均分 然后根据进程时间长短再分多个等级
等级越往下表示耗时越长 每次分到时间越多 但是优先级越低
进程的并行与并发
并行
多个进程同时执行 必须要有多个CPU参与 单个CPU无法实现并行
并发
多个进程看上去像同时执行 单个CPU可以实现 多个CPU肯定也可以
判断下列两句孰对孰错
我写的的程序很牛逼,运行起来之后可以实现14个亿的并行量
并行量必须要有对等的CPU才可以实现
我写的程序很牛逼,运行起来之后可以实现14个亿的并发量
合情合理 完全可以实现 以后我们的项目一般都会追求高并发
目前国内最牛逼的>>>:12306
进程的三状态
就绪态
所有的进程在被CPU执行之前都必须先进入就绪态等待
运行态
CPU正在执行
阻塞态
标签:day36,黏包,len,现象,dict,长度,报头,data,CPU
From: https://www.cnblogs.com/wei0919/p/16900496.html