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面向对象之继承代码详解
Jan 29 Python
python微信跳一跳系列之棋子定位像素遍历
Feb 26 Python
基于Python 装饰器装饰类中的方法实例
Apr 21 Python
Win10下python 2.7.13 安装配置方法图文教程
Sep 18 Python
python 自动轨迹绘制的实例代码
Jul 05 Python
python 动态调用函数实例解析
Oct 21 Python
用Python解数独的方法示例
Oct 24 Python
基于YUV 数据格式详解及python实现方式
Dec 09 Python
解决python 虚拟环境删除包无法加载的问题
Jul 13 Python
python boto和boto3操作bucket的示例
Oct 30 Python
简单介绍Python的第三方库yaml
Jun 18 Python
在NumPy中深拷贝和浅拷贝相关操作的定义和背后的原理
Apr 14 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
DedeCms模板安装/制作概述
2007/03/11 PHP
PHP依赖倒置(Dependency Injection)代码实例
2014/10/11 PHP
javascript之可拖动的iframe效果代码
2008/08/01 Javascript
浅谈javascript 面向对象编程
2009/10/28 Javascript
基于jquery的不规则矩形的排列实现代码
2012/04/16 Javascript
js查错流程归纳
2012/05/04 Javascript
nullJavascript中创建对象的五种方法实例
2013/05/07 Javascript
图标线性回归斜着移动到指定的位置
2013/08/16 Javascript
Angular.js 实现数字转换汉字实例代码
2016/07/14 Javascript
JS中this上下文对象使用方式
2016/10/09 Javascript
jQuery实现 上升、下降、删除、添加一行代码
2017/03/06 Javascript
JS实现点击循环切换显示内容的方法
2017/10/19 Javascript
vue.js  父向子组件传参的实例代码
2017/10/29 Javascript
Vue异步加载about组件
2017/10/31 Javascript
JS中判断某个字符串是否包含另一个字符串的五种方法
2018/05/03 Javascript
js canvas实现星空连线背景特效
2019/11/01 Javascript
Vue设置长时间未操作登录自动到期返回登录页
2020/01/22 Javascript
[01:00:35]2018DOTA2亚洲邀请赛3月30日B组 EffcetVSMineski
2018/03/31 DOTA
python操作mysql代码总结
2018/06/01 Python
实例讲解python中的协程
2018/10/08 Python
python 将对象设置为可迭代的两种实现方法
2019/01/21 Python
详解python多线程之间的同步(一)
2019/04/03 Python
Python用Try语句捕获异常的实例方法
2019/06/26 Python
PYTHON绘制雷达图代码实例
2019/10/15 Python
使用pyshp包进行shapefile文件修改的例子
2019/12/06 Python
python实现根据给定坐标点生成多边形mask的例子
2020/02/18 Python
HTML5 textarea高度自适应的两种方案
2020/04/08 HTML / CSS
澳洲国民品牌乡村路折扣店:Country Road & Trenery Outlet
2018/04/19 全球购物
置业顾问岗位职责
2014/03/02 职场文书
前台接待岗位职责
2015/02/03 职场文书
员工离职通知函
2015/04/25 职场文书
党员转正申请报告
2015/05/15 职场文书
2015年学校财务工作总结
2015/05/19 职场文书
党组织结对共建协议书
2016/03/23 职场文书
2016年清明节网上祭英烈活动总结
2016/04/01 职场文书
Redis缓存-序列化对象存储乱码问题的解决
2021/06/21 Redis