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 17 Python
使用IPython来操作Docker容器的入门指引
Apr 08 Python
Python学习小技巧之列表项的拼接
May 20 Python
Python设计实现的计算器功能完整实例
Aug 18 Python
python将回车作为输入内容的实例
Jun 23 Python
使用urllib库的urlretrieve()方法下载网络文件到本地的方法
Dec 19 Python
使用Python制作简单的小程序IP查看器功能
Apr 16 Python
浅谈pyqt5在QMainWindow中布局的问题
Jun 21 Python
python爬虫 Pyppeteer使用方法解析
Sep 28 Python
Python基础之字符串操作常用函数集合
Feb 09 Python
jupyter notebook快速入门及使用详解
Nov 13 Python
一篇文章教你用python画动态爱心表白
Nov 22 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面向对象 字段的声明与使用
2012/06/14 PHP
CodeIgniter分页类pagination使用方法示例
2016/03/28 PHP
PHP检查URL包含特定字符串实例方法
2019/02/11 PHP
Thinkphp 框架扩展之标签库驱动原理与用法分析
2020/04/23 PHP
根据分辩率调用不同的CSS.
2007/01/08 Javascript
JavaScript入门学习书籍推荐
2008/06/12 Javascript
JS分页控件 可用于无刷新分页
2013/07/23 Javascript
鼠标移到div,浮层显示明细,弹出层与div的上边距左边距重合(示例代码)
2013/12/14 Javascript
JS获取网页图片name属性的方法
2015/04/01 Javascript
jQuery网页选项卡插件rTabs用法实例分析
2015/08/26 Javascript
javascript实现很浪漫的气泡冒出特效
2020/09/05 Javascript
js模式化窗口问题![window.dialogArguments]
2016/10/30 Javascript
微信小程序之购物车功能
2020/09/23 Javascript
VUE中使用Vue-resource完成交互
2017/07/21 Javascript
解决vue-router进行build无法正常显示路由页面的问题
2018/03/06 Javascript
10种JavaScript最常见的错误(小结)
2019/06/21 Javascript
js如何验证密码强度
2020/03/18 Javascript
Vue单页面应用中实现Markdown渲染
2021/02/14 Vue.js
[01:15:16]DOTA2-DPC中国联赛 正赛 Elephant vs Aster BO3 第一场 1月26日
2021/03/11 DOTA
11个并不被常用但对开发非常有帮助的Python库
2015/03/31 Python
基于python元祖与字典与集合的粗浅认识
2017/08/23 Python
Python实现PS滤镜功能之波浪特效示例
2018/01/26 Python
python爬取网页转换为PDF文件
2018/06/07 Python
Python3.7 dataclass使用指南小结
2019/02/22 Python
pyqt5之将textBrowser的内容写入txt文档的方法
2019/06/21 Python
python3实现用turtle模块画一棵随机樱花树
2019/11/21 Python
Python namedtuple命名元组实现过程解析
2020/01/08 Python
python数据类型可变不可变知识点总结
2020/03/06 Python
对CSS3选择器的研究(详解)
2016/09/16 HTML / CSS
请写一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1
2015/07/16 面试题
党员个人思想汇报
2013/12/28 职场文书
领导走群众路线整改措施思想汇报
2014/10/12 职场文书
三严三实心得体会范文
2014/10/13 职场文书
2014年社区民政工作总结
2014/12/02 职场文书
医生个人年终总结
2015/02/28 职场文书
2016年三八红旗手先进事迹材料
2016/02/26 职场文书