python设计tcp数据包协议类的例子


Posted in Python onJuly 23, 2019

一. 问题描述

在tcp编程中,最需要解决的就是粘包分包问题。所以,我们需要在每个数据包前面加上数据包的长度用以分割粘连的包。

二. 包结构的设计

包的组成:包长度+数据域

包长度:用4个字节存储数据域长度,数据域长度即为其所占字节数

数据域:由若干个变量组成,如果是定长变量则不用加变量长度

定长变量:我们人为规定,传输中的int为4字节定长变量

变长变量:那就是字符串啦

文字难理解,那我就画个图吧:

python设计tcp数据包协议类的例子

上图的第一行是数据包的一个总体结构

第二行是数据域内部的一个结构(数据域的变量数量和位置都是我们自己定的,上图只是举一个例子而已)

第三行是具体变量的结构

如果不太清楚这个结构,不要紧,我们来举一个具体的例子

比如我们现在创建一个数据域是这样的数据包:

数据域:666,"你好啊","hello",888

这个数据域一共存储了四个变量,开头和结尾是两个整型变量,中间是两个字符串变量。然后我们对这个数据域构建出来的数据包是这个样子的:

python设计tcp数据包协议类的例子

这下搞明白了吧,那下面就看看怎么用python封装一个类实现上述结构的数据包的组装。

三. 代码实现

class Protocol:
 """
 规定:
 数据包头部占4字节
 整型占4字节
 字符串长度位占2字节
 字符串不定长
 """
 
 def __init__(self, bs=None):
 """
 如果bs为None则代表需要创建一个数据包
 否则代表需要解析一个数据包
 """
 if bs:
  self.bs = bytearray(bs)
 else:
  self.bs = bytearray(0)
 
 def get_int32(self):
 try:
  ret = self.bs[:4]
  self.bs = self.bs[4:]
  return int.from_bytes(ret, byteorder='little')
 except:
  raise Exception("数据异常!")
 
 def get_str(self):
 try:
  # 拿到字符串字节长度(字符串长度位2字节)
  length = int.from_bytes(self.bs[:2], byteorder='little')
  # 再拿字符串
  ret = self.bs[2:length + 2]
  # 删掉取出来的部分
  self.bs = self.bs[2 + length:]
  return ret.decode(encoding='utf8')
 except:
  raise Exception("数据异常!")
 
 def add_int32(self, val):
 bytes_val = bytearray(val.to_bytes(4, byteorder='little'))
 self.bs += bytes_val
 
 def add_str(self, val):
 bytes_val = bytearray(val.encode(encoding='utf8'))
 bytes_length = bytearray(len(bytes_val).to_bytes(2, byteorder='little'))
 self.bs += (bytes_length + bytes_val)
 
 def get_pck_not_head(self):
 return self.bs
 
 def get_pck_has_head(self):
 bytes_pck_length = bytearray(len(self.bs).to_bytes(4, byteorder='little'))
 return bytes_pck_length + self.bs
 
 
if __name__ == '__main__':
 p = Protocol()
 
 p.add_int32(666)
 p.add_str("你好啊")
 p.add_str("hello")
 p.add_int32(888)
 
 r = Protocol(p.get_pck_not_head())
 
 print(r.get_int32())
 print(r.get_str())
 print(r.get_str())
 print(r.get_int32())

代码比较简单,也不够严谨。大家可以按照自己的需求加以修改。

以上这篇python设计tcp数据包协议类的例子就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python根据出生年份简单计算生肖的方法
Mar 27 Python
Python中用于返回绝对值的abs()方法
May 14 Python
Python使用multiprocessing实现一个最简单的分布式作业调度系统
Mar 14 Python
Python多维/嵌套字典数据无限遍历的实现
Nov 04 Python
Django框架模板注入操作示例【变量传递到模板】
Dec 19 Python
python3对拉勾数据进行可视化分析的方法详解
Apr 03 Python
打包python 加icon 去掉cmd黑窗口方法
Jun 24 Python
Python 调用 Windows API COM 新法
Aug 22 Python
pycharm修改file type方式
Nov 19 Python
PyCharm无法引用自身项目解决方式
Feb 12 Python
python为什么会环境变量设置不成功
Jun 23 Python
python一些性能分析的技巧
Aug 30 Python
Django 缓存配置Redis使用详解
Jul 23 #Python
Flask框架中request、请求钩子、上下文用法分析
Jul 23 #Python
python 的 scapy库,实现网卡收发包的例子
Jul 23 #Python
python3+django2开发一个简单的人员管理系统过程详解
Jul 23 #Python
Django框架之DRF 基于mixins来封装的视图详解
Jul 23 #Python
flask框架路由常用定义方式总结
Jul 23 #Python
python处理大日志文件
Jul 23 #Python
You might like
世界上第一台立体声收音机
2021/03/01 无线电
php 处理上百万条的数据库如何提高处理查询速度
2010/02/08 PHP
php强大的时间转换函数strtotime
2016/02/18 PHP
微信公众号开发客服接口实例代码
2016/10/21 PHP
php两点地理坐标距离的计算方法
2018/12/29 PHP
JavaScript中常见陷阱小结
2010/04/27 Javascript
JavaScript中创建对象和继承示例解读
2014/02/12 Javascript
使用jquery解析XML的方法
2014/09/05 Javascript
jQuery时间轴插件使用详解
2015/07/16 Javascript
推荐阅读的js快速判断IE浏览器(兼容IE10与IE11)
2015/12/13 Javascript
Angular.JS内置服务$http对数据库的增删改使用教程
2017/05/07 Javascript
解决vue-cli项目webpack打包后iconfont文件路径的问题
2018/09/01 Javascript
js监听html页面的上下滚动事件方法
2018/09/11 Javascript
微信小程序实现类似微信点击语音播放效果
2020/03/30 Javascript
AI小程序之语音听写来了,十分钟掌握百度大脑语音听写全攻略
2020/03/13 Javascript
vue中watch和computed的区别与使用方法
2020/08/23 Javascript
vue修改Element的el-table样式的4种方法
2020/09/17 Javascript
微信小程序实现可长按移动控件
2020/11/01 Javascript
[03:42]2014DOTA2国际邀请赛 第三日比赛排位扑朔迷离
2014/07/12 DOTA
在Python3中初学者应会的一些基本的提升效率的小技巧
2015/03/31 Python
Python的gevent框架的入门教程
2015/04/29 Python
用Python写一个无界面的2048小游戏
2016/05/24 Python
对Python subprocess.Popen子进程管道阻塞详解
2018/10/29 Python
详解Python 中sys.stdin.readline()的用法
2019/09/12 Python
Python 过滤错误log并导出的实例
2019/12/26 Python
python+requests接口压力测试500次,查看响应时间的实例
2020/04/30 Python
Django全局启用登陆验证login_required的方法
2020/06/02 Python
关于CSS Tooltips(鼠标经过时显示)的效果
2013/04/10 HTML / CSS
深入解析HTML5使用SVG图像时的viewBox属性用法
2015/09/02 HTML / CSS
StubHub西班牙:购买和出售全球活动门票
2017/06/05 全球购物
C#面试问题
2016/07/29 面试题
《藏戏》教学反思
2014/02/11 职场文书
保护黄河倡议书
2014/05/16 职场文书
公司授权委托书
2014/10/17 职场文书
西柏坡观后感
2015/06/08 职场文书
postgresql 删除重复数据案例详解
2021/08/02 PostgreSQL