python学习day32 黏包 struct模块

为什么会出现黏包问题? 

首先只有在TCP协议中才会出现黏包现象

是因为TCP协议是面向流的协议

在发送的数据 传输过程中 有缓存机制 来避免数据丢失

因此 在连续发送小数据的时候 以及接收大小不符的时候都容易出现黏包现象

本质还是因为我们在接受数据的时候不知道发送的数据的长短

怎么解决黏包问题?

在接收端发送要发送的数据的大小

一种是不带struct  一种是带struct  定制协议

 

黏包

http://www.cnblogs.com/Eva-J/articles/8244551.html#_label5

 注意:只有TCP有粘包现象,UDP永远不会粘包

黏包成因:

多个send可能会发生黏包现象

优化算法不优化

发生黏包两种现象:

情况一 发送方的缓存机制

发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据了很小,会合到一起,产生粘包)

情况二 接收方的缓存机制

接收方不及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只收了一小部分,服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包)

 

 如何解决黏包?

存在的问题:
多了一次交互。程序的运行速度远快于网络传输速度,所以在发送一段字节前,先用send去发送该字节流长度,这种方式会放大网络延迟带来的性能损耗

struct模块

该模块可以把一个类型,如数字,转成固定长度的bytes

这个模块可以把要发送的数据长度转换成固定长度的字节。这样客户端每次接收消息之前只要先接受这个固定长度字节的内容看一看接下来要接收的信息大小,那么最终接受的数据只要达到这个值就停止,就能刚好不多不少的接收完整的数据了。

 

import structret = struct.pack('i', 2049)  # pack方法,将对象转换成固定字节长度bytes类型

num = struct.unpack('i', ret)  # 解包
print(num)   # 元组
print(num[0])  # 数字

 

 

连续send  连续receive

 

我们在网络上传输的所有数据,都叫数据包

数据包中的数据,都叫报文

报文里不只有你的数据 ip地址 mac地址 端口号

所有的报文都有报头  相当于协议 接收多少字节 什么顺序 等等

报头可以自己定制

根据报头来解包接收的数据

  复杂的应用上就会用到定制报头

    比如:传输文件的时候

      文件名、大小、类型、路径

 

网络传输中,处处有有协议,协议就是一堆报文和报头 ———字节

协议的解析过程我们不需要关心

我们也可以自定制协议

 

 实现一个大文件的上传或下载:

客户端作发送端:

import socket
import os
import json
import structsk = socket.socket()
sk.connect(('127.0.0.1',8090))# 发文件
# 定制报头
head = {'filepath':r'H:\python\day32','filename':r'05 python fullstack s9day32 strcuct模块定制报头的理论.mp4','filesize':None}
file_path = os.path.join(head['filepath'],head['filename'])
file_size = os.path.getsize(filepath)
head['filesize'] = file_sizejson_head = json.dumps(head)  # 字典转成字符串
bytes_head = json_head.encode('utf-8') # 字符串转bytes类型
head_len = len(bytes_head)  # 报头的长度
pack_len = struct.pack('i', head_len)  # 报头长度转成固定的4字节长度

sk.send(pack_len)  # 先发报头长度
sk.send(bytes_head)  # 再发报头内容
# 然后再发文件内容:
buffer = 1024
with open(filepath, 'rb') as f:while file_size:if file_size >= buffer:content = f.read(buffer)sk.send(content)file_size -= bufferelse:content = f.read(file_size)sk.send(content)break
sk.close

服务端:

import socket
import os
import json
import structsk = socket.socket()
sk.bind(('127.0.0.1',8090))
sk.listen()conn, addr = sk.accept()
# 接收
head_len = conn.recv(4)  # 接收报头长度
head_len = struct.unpack('i', head_len)[0]  # 解包成元组 第一个
json_head = conn.recv(head_len).decode('utf-8')
head = json.loads(json_head)   # 报头

filesize = head['filesize']
buffer = 1024
# 写入文件
with open(head['filename'], 'wb') as f:while filesize:if filesize >= buffer:content = conn.recv(buffer)f.write(content)filesize -= bufferelse:f.write(conn.recv(filesize))breakconn.close
sk.close

 

转载于:https://www.cnblogs.com/happyfan/p/10450905.html

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

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

相关文章

[Leedcode][JAVA][第1300题][转变数组后最接近目标值的数组和][前缀和][二分法][暴力]

【问题描述】[中等] 给你一个整数数组 arr 和一个目标值 target ,请你返回一个整数 value ,使得将数组中所有大于 value 的值变成 value 后,数组的和最接近 target (最接近表示两者之差的绝对值最小)。如果有多种使得…

线性系统的基本理论与运算

线性系统的基本理论与运算 线性系统与非线性系统 线性系统的基本理论 二维线性移不变系统 线性移不变系统 如果一个系统既是线性系统,又是移不变系统,则该系 统是线性移不变系统。

行云管家堡垒机 导入腾讯云主机

行云管家堡垒机 导入腾讯云主机 如何实现了对多家云厂商多种云计算资源的集中管理,从成本、监控、备份、安全等多个维度提供统一运维管控? 工具/原料 行云管家堡垒机方法/步骤 Step1:注册登录 登录行云管家,支持QQ、微信、微博、G…

MyBatis面试题(2020最新版)

目录MyBatis简介MyBatis是什么?ORM是什么为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?传统JDBC开发存在的问题JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的?Mybatis优缺点MyBatis框架适用场景…

Java学习笔记9-2——JavaWeb

文章目录JavaBeanMVC三层架构Filter过滤器Listener监听器JDBC文件上传Servlet邮件发送ServletJavaBean 实体类 JavaBean有特定的写法: 必须要有一个无参构造;属性必须私有化;必须有对应的get/set方法; 一般用来和数据库的字段…

离散傅立叶变换

离散傅立叶变换 一维离散傅里叶变换 二维离散傅里叶变换(2D-DFT) 、图像傅里叶变换的意义 (1)简化计算,也即傅里叶变换可将空间域中复杂的卷 积运算转化为频率域中简单的乘积运算。 (2)对于某些在空间域中难于处理或…

[Leedcode][JAVA][第14题][最长公共前缀][二分][横竖扫描][分治]

【问题描述】[中等] 编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。示例 1:输入: ["flower","flow","flight"] 输出: "fl" 示例 2:输入: ["dog","raceca…

图像傅里叶变换频谱分析

图像的傅里叶频谱特性分析 图像傅里叶频谱关于(/,/)的对称性 图像傅里叶频谱特性及其频谱图 傅里叶变换在图像处理中的应用

[剑指offer]面试题第[37]题[Leedcode][JAVA][第297题][二叉树列的序列化与反序列化][递归][BFS]

【问题描述】[中等] 序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。请设计一个算法来实现二叉树的序列…

Java学习笔记10-1——MyBatis

文章目录简介第一个Mybatis程序搭建环境导入Mybatis,编写配置文件编写代码测试了解一下官方文档的建议实现增删改查select、insert、update、delete使用map进行CRUD模糊查询配置解析(mybatis-config.xml)核心配置文件mybatis-config.xml环境配置(environ…

图像的离散余弦变换

Discrete Cosine Transform,简写为DCT 函数的偶对称性使DCT只有实数域变换结果, 不再涉及复数运算,运算简单,费时少; 又保持了变换域的频率特性; 与人类视觉系统特性相适应; 得到了更加广泛的应用。 二维…

【匈牙利算法】【二分图匹配】【转载】趣写算法系列之--匈牙利算法

转载自:http://blog.csdn.net/dark_scope/article/details/8880547 【书本上的算法往往讲得非常复杂,我和我的朋友计划用一些简单通俗的例子来描述算法的流程】 匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名。匈牙利算法是基于H…

Rest Framework

目录导航 一、RESTful 规范 二、APIView 组件 三、序列化组件 四、认证组件 五、权限组件 六、频率组件 七、分页器组件 一、RESTful 规范 什么是RESTful规范: REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transf…

[剑指offer][JAVA]面试题第[26]题[树的子结构][递归]

【问题描述】[中等] 输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)B是A的子结构, 即 A中有出现和B相同的结构和节点值。例如: 给定的树 A:3/ \4 5/ \1 2 给定的树 B:4 /1 返回 true,因为 B 与…

二分图最大匹配的König定理及其证明

出处:http://www.matrix67.com/blog/archives/116 二分图最大匹配的Knig定理及其证明 如果你看不清楚第二个字母,下面有一个大号字体版本: 二分图最大匹配的Knig定理及其证明 本文将是这一系列里最短的一篇,因为我只打算把Knig定理证了…

【插件介绍】Lombok

Lombok ​ Lombok项目是一个Java库,它会自动插入编辑器和构建工具中,Lombok提供了一组有用的注释,用来消除Java类中的大量样板代码。仅五个字符(Data)就可以替换数百行代码从而产生干净,简洁且易于维护的Java类。 使用步骤&…

图像增强概述

问题背景(Background) 曝光不足或过度的照片-需要增强处理 图像Fourier频谱看不清-需要增强处理 图像有雾-需要 增强处理 车牌识别系统 车牌识别预处理-车牌图像需要增强处理 人脸识别预处理-人脸图像需要增强处理 指纹识别预处理-指纹图像需要增强处理…

并查集入门

quick-find 时间复杂度 quick-union quick-find时间复杂度### quick-union  按SIZE合并 按秩合并 路径压缩 面试了解基本思想 做蓝色 写路径隔代压缩 转载链:https://liweiwei1419.gitee.io/leetcode-algo/

Java学习笔记10-2——MyBatis

文章目录MyBatis详细执行流程使用注解开发面向接口开发使用注解开发复杂查询多对一问题测试环境搭建按照查询嵌套处理(子查询、嵌套查询)按照结果查询(联表查询、联合查询)一对多问题环境搭建按照结果查询(联表查询、联…