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实现得到一个给定类的虚函数
Sep 28 Python
Python实现读取TXT文件数据并存进内置数据库SQLite3的方法
Aug 08 Python
Django 前后台的数据传递的方法
Aug 08 Python
Python函数any()和all()的用法及区别介绍
Sep 14 Python
Python小工具之消耗系统指定大小内存的方法
Dec 03 Python
Python实现图片转字符画的代码实例
Feb 22 Python
django mysql数据库及图片上传接口详解
Jul 18 Python
Django框架HttpResponse对象用法实例分析
Nov 01 Python
使用Django搭建一个基金模拟交易系统教程
Nov 18 Python
Python While循环语句实例演示及原理解析
Jan 03 Python
django 多数据库及分库实现方式
Apr 01 Python
简单了解如何封装自己的Python包
Jul 08 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
php微信公众平台开发之获取用户基本信息
2015/08/17 PHP
PHP实现统计所有字符在字符串中出现次数的方法
2017/10/17 PHP
IE7提供XMLHttpRequest对象为兼容
2007/03/08 Javascript
JQuery 常用方法基础教程
2009/02/06 Javascript
jQuery EasyUI API 中文文档 - Pagination分页
2011/09/29 Javascript
Jquery ajax执行顺序 返回自定义错误信息(实例讲解)
2013/11/06 Javascript
jquery用ajax方式从后台获取json数据后如何将内容填充到下拉列表
2015/08/26 Javascript
在Linux系统中搭建Node.js开发环境的简单步骤讲解
2016/01/26 Javascript
Bootstrap整体框架之CSS12栅格系统
2016/12/15 Javascript
canvas压缩图片转换成base64格式输出文件流
2017/03/09 Javascript
Vue开发中整合axios的文件整理
2017/04/29 Javascript
原生JS实现层叠轮播图
2017/05/17 Javascript
微信小程序中做用户登录与登录态维护的实现详解
2017/05/17 Javascript
微信小程序获取用户openId的实现方法
2017/05/23 Javascript
BootStrap Table 后台数据绑定、特殊列处理、排序功能
2017/05/27 Javascript
ES6中箭头函数的定义与调用方式详解
2017/06/02 Javascript
想用好React的你必须要知道的一些事情
2017/07/24 Javascript
详解webpack + vue + node 打造单页面(入门篇)
2017/09/23 Javascript
vue、react等单页面项目应该这样子部署到服务器
2018/01/03 Javascript
Es6 Generator函数详细解析
2018/02/24 Javascript
微信小程序实现炫酷的弹出式菜单特效
2019/01/28 Javascript
详解vue 动态加载并注册组件且通过 render动态创建该组件
2019/05/30 Javascript
el-table表头根据内容自适应完美解决表头错位和固定列错位
2021/01/07 Javascript
Python 随机生成中文验证码的实例代码
2013/03/20 Python
跟老齐学Python之正规地说一句话
2014/09/28 Python
在Mac OS系统上安装Python的Pillow库的教程
2015/11/20 Python
python列表,字典,元组简单用法示例
2019/07/11 Python
python小程序之4名牌手洗牌发牌问题解析
2020/05/15 Python
Python读取ini配置文件传参的简单示例
2021/01/05 Python
用html5实现语音搜索框的方法
2014/03/18 HTML / CSS
AmazeUI 导航条的实现示例
2020/08/14 HTML / CSS
雅高酒店中国:Accorhotels.com China
2018/03/26 全球购物
The North Face北面法国官网:美国著名户外品牌
2019/11/01 全球购物
校园标语大全
2014/06/19 职场文书
放假通知范文
2015/04/14 职场文书
Java基于字符界面的简易收银台
2021/06/26 Java/Android