一.问题描述

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

二.包结构的设计

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

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

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

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

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

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

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

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

第三行是具体变量的结构

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

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

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

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

这下搞明白了吧,那下面就看看怎么用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_valdef 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.bsdef get_pck_has_head(self):bytes_pck_length = bytearray(len(self.bs).to_bytes(4, byteorder='little'))return bytes_pck_length + self.bsif __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数据包协议类相关推荐

  1. TCP数据包协议格式详解

    出一个专栏把通信协议搞一下吧,万物互联的根本呀. IP 版本4位:4(二进制0100)表示IPv4,6(二进制0110)表示IPv6 报头长度(单位4byte):因为选项长度不确定,取值范围是5-15 ...

  2. python拦截数据包_使用Python进行TCP数据包注入(伪造)

    数据包注入是对已经建立的网络连接通过构建任意协议(TCP...UDP...)然后用原始套接字发送的方式进行妨碍的过程,这种方法被广泛使用在网络渗透测试中,比如DDOS,端口扫描等. 一个数据包由IP头 ...

  3. python拦截tcp数据包,使用python解码TCP数据包

    我正在尝试解码通过TCP连接接收到的数据.数据包很小,不超过100字节.然而,当它们很多的时候,我会收到一些连接在一起的包.有没有办法防止这种情况发生?我用的是蟒蛇 我已经尝试分离数据包,我的来源在下 ...

  4. python拦截tcp数据包_发送低级原始tcp数据包python

    我最近一直在做一个原始数据包的程序.我们最近有一个关于生包的讲座,所以我一直在努力学习和做我的教授告诉我的事情.我的程序有问题,它出现了一个错误,说目标地址是必需的,它是原始的,所以我不想做socke ...

  5. python解析tcp数据包-python解析获取发往本机的数据包并打印

    1.[文件] tcp.py ~ 2KB 下载(69) # -*- coding: cp936 -*- import socket from struct import * from time impo ...

  6. UDP数据包协议格式详解

    源端口目的端口:是0-65535任何数字,在收到请求时系统会为客户端动态分配,0-1023为知名端口号 报文长度(单位4byte):表示udp报头+udp数据总长度,有别于tcp,也没有选项 UDP报 ...

  7. COAP数据包协议格式详解

    Ver:版本编号,占2bit,固定01 T:报文类型,占2bit,CON=00,NON=01,ACK=10,RST=11 CON--需要被确认的请求,如果CON请求被发送,那么对方必须做出响应. NO ...

  8. 计算机网络课程设计:发送TCP数据包

    此文章写于2021年6月29日 一.背景概述 TCP(传输控制协议)是一种面向连接的,可靠的传输层协议.TCP协议在网络层IP协议的基础上,向应用层用户进程提供可靠的,全双工的数据流传输. 二.设计内 ...

  9. 计算机网络课程设计——发送和接收TCP数据包以及发送和捕获ARP数据包

    1.课程设计要求: 发送和接收TCP数据包:TCP是一种面向连接的.可靠的传输层协议.TCP协议工作在网络层IP协议的基础上.本课程设计的目的是设计一个发送和接收TCP数据包的程序,其功能是填充一个T ...

最新文章

  1. Qt: 实现浮点slider和浮点spinbox
  2. Linux每次开机都要source /etc/profile的解决方法
  3. ARM中断分析之四:WinCE的OAL层的中断分析
  4. 12.JAVA基本数据类型
  5. Yum (yellow dog update manager)
  6. 《C和指针》——指针运算
  7. @controlleradvice注解作用_springboot的常用注解分析
  8. 用 Flutter 写一个精美的登录页面(最新版)
  9. zuul网关,springsecurity认证中心 和 Swagger2 整合遇到的问题
  10. 【机器学习】K近邻(KNN)算法详解
  11. 我们算了笔账,月薪过万可能还不配结婚!
  12. Shi-Tomasi角点检测
  13. 模拟信号高速数据采集回放设备
  14. 盖高辛氏衰,天下归之
  15. ubuntu 10.10五笔、rar解压及gedit乱码问题的解决
  16. 京东撸货轻松月入十万,做到这几点,你也可以!
  17. “蔚来杯“2022牛客暑期多校训练营7 L Maximum Range(强连通缩点+网络流输出方案)
  18. 吉德林法则 (Kidlin's Law)的真实案例(2)
  19. 隐适美invisAlign口扫转诊方式(导出口扫数据+线上问诊)
  20. python程序员兼职平台-用Python拓展副业的几种方式

热门文章

  1. 当把Java比喻成一个美少女,她有哪些性格?
  2. 智能营销助手?CRM 从BI到AI的转变
  3. ACCELSTEPPER库实例分析
  4. 基于51单片机和四位数码管的智能计算器算法
  5. 百度或360搜索:地震姜常宏,求传播?!!
  6. SystemVerilog中的solve - before的用法详解
  7. NeurIPS 2022 | 细胞图像分割竞赛正式启动!
  8. 2020.10.25 对象的创建 利用构造函数创建对象 遍历对象属性 遍历函数属性和属性数值for in 内置对象
  9. 学美术还是计算机好,「热门」学画画是手绘还是电脑绘画好?
  10. 手动屏蔽 QQ 图片广告 教程 适用于任何版本