![](https://img2020.cnblogs.com/blog/1774310/202104/1774310-20210428105313778-1575102592.png)
表示层
由于应用数据定义不同,给通信共享造成了障碍,表示层担负了消除这种障碍的任务。表示层的功能是提供统一的网络数据表示,如同应用程序和网络之间的翻译官。也就是说当网络传输流量时,表示层将流量表示为有意义的数据,解决了信息的语法表示并采用统一格式。也就是,说数据的压缩、解压、加密、解密都在该层完成。
由于应用层数据繁多,并且存在多种字符集编码的情况,表示层通过 ASN.1 进行数据的表示,并且在会话层用 BER 编码 ASN.1 的数据。应用协议按照预先定义的抽象语法构造协议数据单元,用于和对等系统进行通信。表示实体则对应用层数据进行编码,变成二进制的比特串,例如把十进制数变成二进制数、把字符变成 ASCII 码等,比特串由下面的传输实体在网络中传送。在各个端系统内部,应用数据被映像成本地的特殊形式,存储在磁盘上或显示在用户终端上。
ASN.1
ASN.1 概念
Abstract Syntax Notation One(ASN.1)抽象语法标记是一种数据定义语言,描述了对数据进行表示、编码、传输和解码的数据格式。它用于定义网络管理系统中的管理信息库(MIB)、应用程序的数据结构和协议数据单元(PDU)。
抽象语法是独立于任何编码技术的,只与应用有关。抽象语法必须满足应用的需要,能够定义应用需要的数据类型和表示这些类型的值。ASN.1 是根据当前网络应用的需求制定的标准,随着网络应用的发展,还会出现新的表示层标准。
ASN.1 的应用场景
ASN.1 独立于机器,独立于程序语言,独立于应用程序的内部表示。应用于定义任何数字信息,包括音频、视频、图片、数据等。它可以解决以下 3 个场景
- 程序语言之间数据类型不同;
- 不同机器平台之间数据的存储方式不同;
- 不同种类的计算机内部数据表示不同。
例如一个 ASN.1 对个人信息记录的定义如下,可以等看完下面的内容后再回头试着读懂。
书写规则
- 书写的布局是无意义的,多个空格和空行等效于一个空格;
- 用于表示值和字段的标识符、类型指针(类型名)和模块名由大小写字母、数字和短线组成;
- 标识符以小写字母开头;
- 类型指针和模块名以大写字母开头;
- ASN.1 定义的内部类型全部用大写字母表示;
- 关键字全部用大写字母表示;
- 注释以一对短线(-)开始,以一对短线或行尾结束。
在 ASN.1 中,用符号 ::= 表示产生式,读做“定义为”。
ASN.1 标签类型
在ASN.1中,每一个数据类型都有一个标签(tag),标签有类型和值集合两种属性。标签的类型分为以下4种:
标签类型 | 说明 |
---|---|
通用标签 UNIVERSAL | 由标准定义的,适用于任何应用 |
应用标签 APPLICATION | 由某个具体应用定义的类型 |
上下文专用标签 | 在文本的一定范围(例如一个结构)中适用 |
私有标签 PRIVATE | 用户定义的标签 |
ASN.1 数据类型
ASN.1定义的数据类型有 20 多种,标签类型都是 UNIVERSAL。ASN.1 定义的通用类型标签如下所示:
这些数据类型可分为 4 大类:
数据类型 | 说明 |
---|---|
简单类型 | 由单一成分构成的原子类型 |
构造类型 | 由两种以上成分构成的构造类型 |
标签类型 | 由已知类型定义的新类型 |
其他类型 | 包括 CHOICE 和 ANY 两种类型 |
简单类型
除了 UNIVERSAL 16 和 UNIVERSAL 17 之外的标签都是简单类型,特点是可以直接定义它们的值的集合,可以把这些类型作为原子类型构造新的数据类型。
第一组-基本类型
简单类型可以分为 4 组,第一组包括 BOOLEAN、INTEGER、BIT STRING、OCTET STRING、REAL 和 ENUMERATED 等,可以称之为基本类型。定义整数类型的例子如下:
EthernetNumberCollisionsRange::=INTEGER{minimum(0),maximum(1000)}
值得一提的是枚举类型 ENUMERATED,它是整数列表,对每个元素(整数)取名。其中整数只是符号,不能做算术运算。定义枚举类型的例子如下:
EthernetAdapterStatus::=ENUMERATED{normal(0),degraded(1),offline(2),failed(3)}
第二组-字符串类型
第二组包括各种字符串类型,标签为 UNIVERSAL 18~22 和 UNIVERSAL 25~27,都是 OCTET STRING 类型的子集。
第三组-信息对象类型
第三组包括 OBJECT IDENTIFIER 和 Object Descriptor 两种类型,泛指网络中传输的任何信息对象,例如标准文档、抽象语法和传输语法、数据结构和管理对象等。
数据类型 | 说明 |
---|---|
OBJECT IDENTIFIER 对象 | 由一个整数序列组成,它唯一地标识一个对象 |
Object Descriptor | 以人工可读的形式描述信息对象的语义 |
第四组
数据类型 | 说明 |
---|---|
NULL | 空类型,没有值,只占用结构中的一个位置,该位置可能出现或不出现数据。 |
EXTERNAL | 外部类型,即标准之外的文档定义的类型 |
UTCTime | (世界通用时)格式 YYMMDDhhmmss,加后缀表示本地时间 |
GeneralizedTime | 格式是 yyyymmddhhmmss.x,加后缀可表示本地时间 |
构造类型
构造类型有序列和集合两种,分别用 SEQUENCE 和 SEQUENCE OF 表示不同类型和相同类型元素的序列,分别用 SET 和 SET OF 表示不同类型和相同类型元素的集合。序列和集合的区别是前者的元素是有序的,而后者是无序的。
定义序列
定义序列的语法如下,其中 NamedType 是类型指针,序列的每一成分类型可跟关键字 OPTIONAL (任选)或 DEFAULT (默认值),COMPONENTS OF 子句用于指示另一个被包含的类型。
SequenceType::=SEQUENCE{ElementTypeList}| SEQUENCE {}
定义 SEQUENCE OF 类型的语法:
SequenceOfType::=SEQUENCE OF Type | SEQUENCE
定义序列类型的例子如下:
定义集合
定义 SET 和 SET OF 的语法是类似的:
SetType::=SET {ElementTypeList}| SET {}
SetOfType::=SET OF Type | SET
定义集合类型的例子如下:
标签类型
该类型是应用或用户加在某个类型上的标签,对于一个应用标签 [APPLICATION X],一个类型可以有多个类型名。
结构类型(序列或集合)中,可用上下文专用标签区分类型相同的元素,例如集合中有 3 个同样类型的元素,分别指本人、父亲、母亲的名字,可以用 [1]、[2] 和 [3] 表示。
其他类型
CHOICE 和 ANY 是没有标签的类型,因为它们的类型和值未定,当这种类型的变量被赋值时,其类型和标签确定(运行时确定)。
CHOICE 类型是可选类型列表,仅其中一个类型可被采用,产生一个值。
ChoiceType::= CHOICE{AlternativeTypeList}
ANY 类型表示任意类型的任意值,实际出现的类型也是未知的.
AnyType::=ANY | ANY DEFINED BY identifier
子类型
子类型是由限制父类型的值集合而导出的类型,子类型的值集合是父类型的子集,子类型还可以再产生子类型。产生子类型的方法有 6 种:
单个值
列出子类型可取的各个值。如定义小素数为整数类型的子集:
SmallPrime::=INTEGER(2|3|5|7|11|13|15|17|19|23|29)
包含子类型
用关键字 INCLUDES,说明被定义的类型包含了已有类型的所有的值。例如:
First-half::=Months(INCLUDES First-quarter | INCLUDES Second-quarter)
值区间
仅应用于整数和实数类型,指出取值区间。PLUS-INFINITY 和 MINUS-INFINITY 分别表示正、负最大值,MAX 和 MIN 分别表示父类型可允许的最大值和最小值,区间可以是闭区间或开区间(加上符号“<”)。例如:
PositiveInteger::=INTEGER(0<..PLUS-INFINITY)
PositiveInteger::=INTEGER(1..PLUS-INFINITY)
PositiveInteger::=INTEGER(0<..MAX)
PositiveInteger::=INTEGER(1..MAX)
这四个定义是等价的。
可用字符
用于字符串类型,限制可使用的字符集。例:
TouchToneButtons::=IA5String(FROM("0"|"1"|"2"|"3"|"4"|"5"|"6"|"8"|"9"|"*"|"#"))
限制大小
可对5种类型限制其规模大小,例如限制比特串、字节串或字符串的长度,限制构成序列或集合的元素(同类型)个数等。例如参数表包含最多 12 个参数:
ParameterList::=SET SIZE(0..12) OF Parameter
内部子类型
假定有一种协议数据单元:
PDU::=SET{
alpha[0] INTEGER,
beta [1] IA5String OPTIONAL,
gamma[2] SEQUENCE OF Parameter,
delta[3] BOOLEAN
}
例如子类型定义为要求布尔值必须是 FALSE,整数值必须是负的:
TestPDU::=PDU(WITH COMPONENTS{....delta(FALSE),alpha(MIN.. <0)})
子类型定义为要求 beta 参数必须出现,其值为 5 或 12 个字符组成的串:
FurtherTestPDU::=TestPDU(WITH COMPONENTS{....beta(SIZE 5|12) PRESENT})
宏定义
模块定义
模块类似于 C 语言中的结构体,用于定义一个抽象数据类型。模块定义的形式为:
<modulereference> DEFINITIONS::= //模块名和标识符
BEGIN
EXPORTS //出口部分
IMPORTS //模块引用的类型和值
AssignmentList //模块定义的类型、值和宏定义
END
宏表示
宏定义可以看作类型的类型(超类型),也可以看类型的模板,可用于制造形式相似、语义相关的数据类型。
概念 | 说明 |
---|---|
宏表示 | ASN.1提供的一种表示机制,用于定义宏 |
宏定义 | 用宏表示定义的一个宏,代表一个宏实例的集合 |
宏实例 | 用具体的值代替宏定义中的变量而产生的实例,代表一种具体的类型 |
宏定义的一般形式如下:
<macroname> MACRO::= //宏名字(全大写)
BEGIN
TYPE NOTATION::=<new-type-syntax> //类型表示
VALUE NOTATION::=<new-value-syntax> //值表示
[<supporting-productions>] //支持产生式
END
参考资料
《计算机网络管理(第三版)》雷震甲 编著,西安电子科技大学出版社