通信协议

1 .通信协议的概念及其要素

OSI 开放互联参考模型中,对等实体之间数据单元在发送方逐层封装,在接收方的逐层解析。发送方N 层实体从N+1 层实体得到的数据包称为服务数据单元(Service Data UnitSDU )。N 层实体只将其视为需要本实体提供服务的数据,将服务数据单元进行封装,使其成为一个对方能够理解的数据单元(Protocol Data UnitPDU ),封装过程实际上是为SDU 增加对等实体间约定的控制信息(Protocol Control InformationPCI )的过程。

为了保证网络的各个功能的相对独立性,以及便于实现和维护,通常将协议划分为多个子协议,并且让这些协议保持一种层次结构,子协议的集合通常称为协议簇。

网 络协议的分层有利于将复杂的问题分解成多个简单的问题,从而分而治之。各层的协议由各层的实体实现,通信双方对等层中完成相同协议功能的实体称为对等实 体。对等实体按协议进行通信,所以协议反映的是对等层的对等实体之间的一种横向关系,严格地说,协议是对等实体共同遵守的规则和约定的集合。

通信协议精确地定义了双方通信控制信息和解释信息:发送方能将特定信息(文本、图片、音频、视频)按协议封装成指定格式的数据包,最终以串行化比特流在网络上传输;接收方接收到数据包后,根据协议将比特流解析为本地化数据,从而获取对方发送过来的原始信息。

通信协议包括三个要素:

1 )语法:规定了信息的结构和格式;

2 )语义:表明信息要表达的内容;

3 )同步:规则涉及双方的交互关系和事件顺序。

整个计算机网络的实现体现为协议的实现,TCP/IP 协议是Internet 互联网的核心协议。

2 .通信协议开发步骤

1 ) 协议的开发主要包括协议设计、协议形式描述、协议实现和协议一致性测试。协议的开发过程与步骤如图1 所示。

    1 协议开发过程与步骤

2 协议设计过程中的分组发送接收模型如图2 所示。

2 协议设计过程中的分组发送接收模型

3 )协议的一致性测试

协议的一致性测试是指测试协议能否按照预想的控制策略实现正确的通信,主要体现在数据包通过信道从信源传送到信宿后,信宿能够根据协议正确的解析出原始信息。

协议的一致性测试如图3 所示。

3 协议一致性测试环境

根据测试环境的可以分为局部测试和分布式测试,如图4 所示。

4 局部测试法、分布式测试法

3 .数据包和数据报

为方便描述自定义协议,还是借用数据包和数据报来描述封装数据单元和传输数据单元,但这里的数据包和数据报完全不同于TCP/IP 架构中的PacketDatagram 概念。

下文所述的数据包指封装的基本单位,以TLVType-Length-Value )格式封装基本消息单位;数据报Package 是传输的基本单位,头部包含序列号和命令信息。接收端根据命令信息分辨事件类型,做出不同的解析。报文实体是多个TLV 数据包组成的链表。

 

 

 

4.数据包TLV 的设计

从应用层HTTP 协议,到超文本置标语言HTMLHyperText Mark-up Language ),再到可扩展置标语言XMLExtensible Markup Language ),它们提供了数据的格式化存储、传输和格式化显示的规范,是网络通信的基石。然而HTTP 协议以及HTML/XML 置标语言的本质就是定义一堆标签(Tag )对数据进行串行化序列化,然后接收方再根据标签解析、还原数据。

自定义通信协议的关键是对数据包的合理构造(construct )和正确解析(parse ),即制定编解码规则。

抽象语法标记ASNAbstract Syntax Notation BER 的长度确定的编码方式,由3 部分组成Identifier octetsLength octetsContents octets ,实际上这就是一中TLVType-Length-Value )模型:类型字段(TypeTag )是关于标签和编码格式的信息;长度字段(Length )定义数值的长度; 内容字段(Value )表示实际的数值。

因此,一个编码值又称TLV 三元组。编码可以是基本型或结构型,如果它表示一个简单类型的、完整的显式值,那么编码就是基本型(primitive );如果它表示的值具有嵌套结构,那么编码就是结构型 (constructed )。

TLV 编码就是指对TypeTag )、LengthValue 进行编码,形成比特流数据包;解码是编码的逆过程,是从比特流缓冲区中解析还原出原始数据。

采用C++ 编程语言设计TLV 协议类,其类视图如图5 所示。

5 CTLV 类视图

目前只提供设置整形值(int 型)的setValue_Int 和设置字符串值(C_String 型)的SetValue_Cstring 两个接口。

TLV 将数据封装成包的格式如表1 所示。

1 TLV 包格式

TLV

头部

包实体

m_dwTag

m_nLen

m_pValue

     

TLV 的接口说明:

1 )值类型标签 m_vtTag 是内部辅助枚举变量,它根据构造TLV 时传递的服务类型标签m_dwTag 来确定。

2TLV::m_nLen 在为TLV 设置具体值时确定。

3TLV 包的封装:

1 )使用Tag 参数创建一个TLV 对象后,调用TLV::setValue_* 方法为TLV 填充具体值;

2 )调用TLV::toBuffer 方法打包到缓冲区streamBuffer

4TLV 包的解析:创建一个TLV 对象后,调用TLV::fromBuffer 方法从缓冲区streamBuffer 解析出TLV

5 )封装和解析涉及到本机字节顺序和网络字节顺序的转换问题。

6 )调用TLV::setValue_* 方法填充TLV 时,统一字节边界数为4

5. 数据报Package 的设计

不同于底层的数据包/ 数据报只是对数据层次的封装解析,实际应用程序是以事件驱动的,因此必须注册不同的信令(事件类型标签),然后填充到数据报中。接收端根据信令做出相应的事件处理。

例如在C/S 通信系统中,客户端往往要先登录,通过服务器端的校验才能进行后续通信。因此客户端运行后,需要构造并向服务器端发送含有LOGIN 信令的包含用户名字符串strUserName 和密码字符串strPassWord 的数据报;服务器端解析LOGIN 信令后做校验处理,然后发送含有LOGIN_RESPONSE 信令和校验结果的回执数据报给客户端。

采用C++ 编程语言设计Package 类,其类视图如图6 所示。

6 CPackage 类视图

Package 类将TLV 封装成包的格式如表2 所示。

2 Package 包格式

Package

头部

序列号

包实体

m_nCmdLen

m_dwCmdID

m_dwCmdState

m_nSeqNo

Count*Tlv

         

Package 的接口说明:

1Package::m_nCmdLen 是整个Package 包的长度,将其作为首个字段的好处在于当传送大数据包时,接收方可以根据数据长度来控制读状态,从而将一个大数据包分批接收。

2Package::m_nCmdLen 在构造函数中初始化为16 ,在调用Package::addTLV 方法填充包实体时增长。

3Package 包的封装:

1 )创建Package 对象后,调用Package::setHeader 方法填充头部信令;

2 )创建TLV 对象并填充数据,再调用Package::addTLV 方法填充包实体;

3 )调用Package::toBuffer 方法将Package 打包到缓冲区streamBuffer

4Package 包的解析:

1 )先创建一个Package 对象,调用Package::fromBuffer 方法从缓冲区streamBuffer 先解析出Package 的头部和序列号,再从剩余缓冲区中解析出TLV 并将其串行化到链表。

2 )调用 Package:: getTLV 方法根据Tag 从链表中查找具体TLV 包,再调用TLV::getValue 方法取得具体值。

5Package:: toBuffer 方法和 Package:: fromBuffer 方法主要遍历 Package::m_TLV_List 列表,然后调用TLV::toB uffer 方法和TLV::fromBuffer 方法解析出TLV 数据单元。

TLV 数据包的功能测试(主要是本地测试)

鉴于实际通信数据最后都要转换成比特流,故只测试发送字符串类型的变量,仅测试协议能否正确打包、解析。其他类型的普通数据都可以转换成字符串传输,最后,接收方根据 m_dwTag 确定值类型m_vtTag ,解析出具体值。

TLV::setValue_C_String 方法填充TLV 的测试,需要考虑字节对齐问题。对于长度为4 字节倍数的C 状态字符串,打包时省去末尾的‘/0’ 结束标志符。需要测试长度非4 倍数的字符串和长度为4 倍数的字符串。

经本地测试,调用TLV::setValue_Int 方法和TLV::setValue_C_String 方法构造整形和字符串时,能够正确封装、正确解析。

Package 数据报的功能测试,主要是将TLV 组合成包,然后添加信令,完成特定的通信。对登陆LOGIN 和发送消息SUBMIT_SM 的测试表明Package 协议能正确封装、正确解析。

在实际项目中使用Package 通信协议,对于稍大一点的数据块需要控制好读的步骤,以便能接收整包完整的信息。

你可能感兴趣的:(String,网络,测试,语言,login,Primitive)