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网络编程学习笔记(九):数据库客户端 DB-API
Jun 09 Python
django 自定义用户user模型的三种方法
Nov 18 Python
Python中处理字符串之islower()方法的使用简介
May 19 Python
Python字符串逐字符或逐词反转方法
May 21 Python
Python实现获取汉字偏旁部首的方法示例【测试可用】
Dec 18 Python
Python删除n行后的其他行方法
Jan 28 Python
对DataFrame数据中的重复行,利用groupby累加合并的方法详解
Jan 30 Python
Python字符串的一些操作方法总结
Jun 10 Python
python实现连续变量最优分箱详解--CART算法
Nov 22 Python
PyQt5中向单元格添加控件的方法示例
Mar 24 Python
Python实现给PDF添加水印的方法
Jan 25 Python
Django使用channels + websocket打造在线聊天室
May 20 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 信息采集程序代码
2009/03/17 PHP
php画图实例
2014/11/05 PHP
PHP ajax 异步执行不等待执行结果的处理方法
2015/05/27 PHP
学习php设计模式 php实现桥梁模式(bridge)
2015/12/07 PHP
jQuery 网易相册鼠标移动显示隐藏效果实现代码
2013/03/31 Javascript
eclipse导入jquery包后报错的解决方法
2014/02/17 Javascript
Javascript中的异步编程规范Promises/A详细介绍
2014/06/06 Javascript
nodejs下打包模块archiver详解
2014/12/03 NodeJs
javascript日期格式化方法小结
2015/12/17 Javascript
BootStrap响应式导航条实例介绍
2016/05/06 Javascript
JS 事件绑定、事件监听、事件委托详细介绍
2016/09/28 Javascript
JavaScript三种绑定事件方式及相互之间的区别分析
2017/01/10 Javascript
如何在Angular2中使用jQuery及其插件的方法
2017/02/09 Javascript
Vuejs 组件——props数据传递的实例代码
2017/03/07 Javascript
jquery实现点击a链接,跳转之后,该a链接处显示背景色的方法
2018/01/18 jQuery
Bootstrap标签页(Tab)插件切换echarts不显示问题的解决
2018/07/13 Javascript
AntV F2和vue-cli构建移动端可视化视图过程详解
2019/10/08 Javascript
vue 通过base64实现图片下载功能
2020/12/19 Vue.js
[50:50]完美世界DOTA2联赛PWL S3 INK ICE vs DLG 第一场 12.20
2020/12/23 DOTA
跟老齐学Python之总结参数的传递
2014/10/10 Python
python定时器(Timer)用法简单实例
2015/06/04 Python
Python列表list操作符实例分析【标准类型操作符、切片、连接字符、列表解析、重复操作等】
2017/07/24 Python
python批量替换页眉页脚实例代码
2018/01/22 Python
对python的bytes类型数据split分割切片方法
2018/12/04 Python
python中的colorlog库使用详解
2019/07/05 Python
Flask框架重定向,错误显示,Responses响应及Sessions会话操作示例
2019/08/01 Python
Django上线部署之IIS的配置方法
2019/08/22 Python
python智联招聘爬虫并导入到excel代码实例
2019/09/09 Python
python实现快递价格查询系统
2020/03/03 Python
Python气泡提示与标签的实现
2020/04/01 Python
pymysql之cur.fetchall() 和cur.fetchone()用法详解
2020/05/15 Python
森海塞尔美国官网:Sennheiser耳机与耳麦
2017/07/19 全球购物
阿联酋最好的手机、电子产品和家用电器网上商店:Eros Digital Home
2020/08/09 全球购物
入职担保书怎么写
2014/05/12 职场文书
百年校庆感言
2015/08/01 职场文书
2016年大学生暑期社会实践方案
2015/11/26 职场文书