TLV协议是一种通讯协议,一般将数据封装成TLV的形式,即Tag,Length,Value。协议就是指通信双方对数据传输控制的一种规定,规定了数据格式,同步方式,传送速度,传送步骤的问题作出统一的规定。可以理解为两个节点之间为了协同工作,协商一定的规则和约定。例如我们会规定字节序,各个字段类型等。

TLV 是一种可变的格式,其中:

  • T 可以理解为 Tag 或 Type ,用于标识标签或者编码格式信息;
  • L 定义数值的长度;
  • V 表示实际的数值。

T 和 L 的长度固定,一般是2或4个字节,V 的长度由 Length 指定。

图例帧格式如下所示:

由于用到这块,我就自己弄了一个python下的仿真代码,这里就给大家demo一下了:

 服务端:

  

import socket
import threading
import pickle import time
from TLV import *
# 定义保存所有socket的列表
socket_list = []
# 创建socket对象
ss = socket.socket()
# 将socket绑定到本机IP和端口
ss.bind(('localhost', 2333))
# 服务端开始监听来自客户端的连接
ss.listen()
tlv = TLV(t_ext=7, l_ext=7) def server_target(s):
try:
# 采用循环不断地从socket中读取客户端发送过来的数据
while True:
line = input()
if line is None or line == 'exit':
break time.sleep(2)
tlv.add(8,line)
data = pickle.dumps(tlv)
s.send(data)
except Exception:
print(Exception.with_traceback())
while True:
# 此行代码会阻塞,将一直等待别人的连接
s, addr = ss.accept()
#socket_list.append(s)
# 每当客户端连接后启动一个线程为该客户端服务
threading.Thread(target=server_target, args=(s, )).start()

客户端:

import socket
import threading
import pickle
from TLV import *
# 创建socket对象
s = socket.socket()
# 连接远程主机
s.connect(('localhost', 2333)) def read_from_server(s):
try:
data = pickle.loads(s.recv(2048))
# test
tlvp = TLVParser(data.buffer, t_ext=7, l_ext=7)
for avp in tlvp.parse():
print("%d(%d): %s" % (avp["type"], avp["length"], avp["value"]))
# return s.recv(2048).decode('utf-8')
return tlvp
# 如果捕获到异常,则表明该socket对应的客户端已经关闭
except:
# 删除该socket
socket_list.remove(s) # ① def read_server(s):
try:
while True:
contend = read_from_server(s)
if contend is None:
break
except:
print(Exception.with_traceback()) # 客户端启动线程不断地读取来自服务器的数据
threading.Thread(target=read_server, args=(s, )).start() # ①

 TLV的实现:

from scapy.all import *

class TLVError(Exception):
pass class TLV:
def __init__(self, tl_in_l=False, t_ext=0, l_ext=0):
self.buffer = ""
self.tl_in_l = tl_in_l
self.t_ext = t_ext
self.l_ext = l_ext def _int(self, i, ext):
maxi = 1<<8
if ext > 0:
maxi = (1 << ext)
holdstr = ""
holder = i
extend = 0
count = 1
while holder >= maxi:
count += 1
newnum = (holder & (maxi - 1))
holdstr = chr(newnum | extend) + holdstr
extend = maxi
holder /= maxi holdstr = chr(holder | extend) + holdstr
return holdstr def _t(self, t):
if self.t_ext == 0 and t > 256:
raise TLVError("type > 256 and no extension bit set")
return self._int(t, self.t_ext) def _l(self, l):
if self.l_ext == 0 and l > 256:
raise TLVError("length > 256 and no extension bit set")
return self._int(l, self.l_ext) def add(self, t, v, l=None):
self.buffer += self._t(t)
length = 0 if l is None else l if self.tl_in_l:
length += t if l is None:
length += len(v) self.buffer += self._l(length)
self.buffer += v def __str__(self):
return self.buffer def __repr__(self):
return self.buffer class TLVParser:
def __init__(self, buffer, tl_in_l=False, t_ext=0, l_ext=0):
self.buffer = buffer
self.tl_in_l = tl_in_l
self.t_ext = t_ext
self.l_ext = l_ext
self.offset = 0 def _get_i(self, i_ext):
try:
byte = ord(self.buffer[self.offset])
except IndexError:
raise TLVError("Not enough data")
ext = 1 << (i_ext if i_ext > 0 else 8)
i = 0
while byte & ext:
i += (byte & (ext - 1))
i <<= i_ext
self.offset += 1
try:
byte = ord(self.buffer[self.offset])
except IndexError:
raise TLVError("Not enough data")
i += byte
self.offset += 1
return i def _get_tlv(self):
t = self._get_i(self.t_ext)
l = self._get_i(self.l_ext)
if self.offset + l > len(self.buffer):
raise TLVError("Buffer not long enough to encompass TLV")
v = self.buffer[self.offset:self.offset+l]
self.offset += l
return (t, l, v) def parse(self):
while self.offset < len(self.buffer):
t, l, v = self._get_tlv()
yield {
"type": t,
"length": l,
"value": v,
} # Test/example program for building TLVs and parsing the TLVs
if __name__ == "__main__":
tlv = TLV(t_ext=7, l_ext=7)
tlv.add(10, "Foobar")
tlv.add(16, "Bladibla")
# hexdump(tlv)
tlvp = TLVParser(tlv.buffer, t_ext=7, l_ext=7)
for avp in tlvp.parse():
print ("%d(%d): %s" % (avp["type"], avp["length"], avp["value"]))

  具体的代码运行结果就不贴了,对懂得python的同学来说,这个很简单的。

通信协议TLV的介绍及在python下的代码实现及仿真的更多相关文章

  1. python下的orm基本操作(1)--Mysql下的CRUD简单操作(含源码DEMO)

    最近逐渐打算将工作的环境转移到ubuntu下,突然发现对于我来说,这ubuntu对于我这种上上网,收收邮件,写写博客,写写程序的时实在是太合适了,除了刚接触的时候会不怎么完全适应命令行及各种权限管理, ...

  2. Python下的OpenCV学习 01 —— 在Linux下安装OpenCV

    一.OpenCV简要介绍 OpenCV是一个跨平台的计算机视觉库,可以运行在Windows.Linux.MacOS等操作系统上.OpenCV提供了众多语言的接口,其中就包含了Python,Python ...

  3. Python下划线简介

    Python中下划线的5种含义 分享一篇文章:The Meaning of Underscores in Python. 本文介绍了Python中单下划线和双下划线("dunder" ...

  4. Python下探究随机数的产生原理和算法

    资源下载 #本文PDF版下载 Python下探究随机数的产生原理和算法(或者单击我博客园右上角的github小标,找到lab102的W7目录下即可) #本文代码下载 几种随机数算法集合(和下文出现过的 ...

  5. python下划线的5种含义

    本文介绍了Python中单下划线和双下划线("dunder")的各种含义和命名约定,名称修饰(name mangling)的工作原理,以及它如何影响你自己的Python类. 单下划 ...

  6. python下wxpython程序国际化的实践(中文英文切换)

    一.什么是python的国际化(I18N) 有关I18N,百度上解释一大堆,个人比较喜欢这个说法. i18n是 Internationalization 这个英文的简写,因为International ...

  7. Python下图片的高斯模糊化的优化

    资源下载 #本文PDF版下载 Python下图片的高斯模糊化的优化(或者单击我博客园右上角的github小标,找到lab102的W6目录下即可) #本文代码下载 高斯模糊(一维)优化代码(和本文方法集 ...

  8. 利用python 下paramiko模块无密码登录

    利用python 下paramiko模块无密码登录   上次我个大家介绍了利用paramiko这个模块,可以模拟ssh登陆远程服务器,并且可以返回执行的命令结果,这次给大家介绍下如何利用已经建立的密钥 ...

  9. python下的自动化测试--selenium 验证码输入问题

    之前一直在研究scrapy下数据抓取,在研究ajax数据抓取时碰巧研究了一下selenium,确实很实用,不过只做scrapy下的数据抓取,不怎么合适,一是性能的损耗,一直需要开一个浏览器,二是对于爬 ...

随机推荐

  1. nyoj 51-管闲事的小明(遍历,比较)

    51-管闲事的小明 内存限制:64MB 时间限制:4000ms Special Judge: No accepted:9 submit:20 题目描述: 某校大门外长度为L的马路上有一排树,每两棵相邻 ...

  2. django_4:数据库0——配置数据库

    使用Mysql数据库 (python需要能连接上mysql,见别的文档:python3+django 支持 mysql) 启动mysql服务 修改setting.py同目录 下的__init__.py ...

  3. 工作日志,error parsing query: unable to find time zone

    工作日志,error parsing query: unable to find time zone 坑 Windows 系统使用influxdb数据库,在执行查询语句时提示 ERR: error p ...

  4. webapi跨域使用session

    在之前的项目中,我们设置跨域都是直接在web.config中设置的. 这样是可以实现跨域访问的.因为我们这边一般情况下一个webapi会有多个网站.小程序.微信公众号等访问,所以这样设置是没有问题的. ...

  5. Stream系列(四)Sorted方法使用

    排序和反向排序 EmployeeTestCase.java package com.example.demo; import lombok.Data; import lombok.ToString; ...

  6. RPM命令执行失败:bash: rpm: 未找到命令...

    出现错误截图如下: 这是由于误操作导致rpm文件缺失导致 将另一台完好的服务器上RPM文件及缺失文件上传至异常服务器上即可修复 异常服务器A:192.168.1.230 完好服务器B: 任意 服务器B ...

  7. Python大神必须掌握的技能:多继承、super和MRO算法

    本文主要以Python3.x为例讲解Python多继承.super以及MRO算法. 1. Python中的继承 任何面向对象编程语言都会支持继承,Python也不例外.但Python语言却是少数几个支 ...

  8. Android Binder机制介绍

    做过Android开发的同学可能有些体会,入门初期,工作内容主要是实现各式各样的UI界面,以及实现应用的业务逻辑.在这个阶段,我们会逐渐熟悉View系统,逐渐学会实现各种各样的界面以及动画效果.再往后 ...

  9. windows下python IDE安装注意事项&Python安装及编辑器UliPad安装

    python下载地址: http://www.python.org/download/releases/2.7.6/ 我自己用的是ulipad  ,但是注意  ulipad和python的版本一定要配 ...

  10. VisualStudio2012编辑器错误

    https://blogs.msdn.microsoft.com/webdev/2014/11/11/dialog-box-may-be-displayed-to-users-when-opening ...