前言
一天,老板丢了一份网络协议给你:“把这个实现一下吧。” 你:“????”
我是谁?我在哪里?协议是什么?于是,你懵逼的苦逼的一天就此拉开了序幕了。 关于网络协议的基础,我这里不打算说,想谈谈,拿到一份协议,我们要怎么办?顺便记录一下自己对网络协议实现的理解。
这两篇文章希望能够帮助大家从零开始实现一个应用层协议。
协议的主要构成
一个协议栈可能会包含1~n层,不过每层的结构都是一致的,因此我们只要能够理解单层协议,也就自然可以理解n层的协议栈了。
整体结构
典型的单层网络协议构成如下图:
可以看到,一个协议栈由横向和纵向两部分构成:
- 一个协议的主要交互对象是使用该协议的两端(也可以是多端)实体entity
- 两端的实体被称为同层对等实体,他们通常会被区分为服务端和客户端;
- 两端之间通过PDU(协议数据单元)也就是常说的符合本协议层规范的数据包进行交互。
- 一个k层的实体向上层(k+1层)实体提供服务Service,同时调用下层提供的服务
- 这个上层可以是上层协议,也可以是使用第k层协议的应用;
- 我们常见的下层如TCP,UDP,IP等;
- 协议提供的服务主要通过一组Service primitive(服务原语),定义服务接口。
因此,一个网络协议的核心要素主要有:协议Protocol和PDU(Protocol Data Unit)协议数据单元、以及服务Service和服务原语,我们阅读协议的时候大致也可以先从这几个要素入手。
协议和协议数据单元PDU (Protocol Data Unit)
协议和协议数据单元构成了协议栈的横向信息交换的规则定义。
协议
协议主要是同层对等实体之间交换信息的规则。这个信息交换由PDU来进行支持。
PDU
PDU其实就是双方协议实体约定好的沟通的数据规范格式。 讲到PDU,一般容易牵扯到一个概念叫做SDU。简单说,本层实体处理的用户数据集合=SDU,SDU+本层的协议包头(尾)构成的集合=PDU。
- 对于PDU的发送端协议实体来说,通过对消息类型域的编码并打包本层PDU,将本协议实体的意图传达给对端。
- 对接收方协议实体来说,通过解析PDU,获取PDU中本层的协议包头,理解本协议的各消息类型域,从而理解对端的意图。
- 一般来说,PDU分成数据型PDU和管理型PDU
- 数据型PDU主要用于传输用户数据
- 管理型PDU主要用于实现协议的管理功能,典型的如建立连接、断开连接、或者keep alive的PDU
典型的消息帧结构如下表,表中的每一行即为一个消息类型域:
服务 Service 和服务原语 Service Primitive
如果将PDU认为是两个同层不同实体之间横向的沟通方式,那么服务原语就是同一应用中不同层实体之间上下纵向的沟通接口。
服务
在同一系统中,服务是本协议(N层实体)承诺向上层(N+1层实体)提供的能力,此时,服务用户(N+1层实体)和服务提供者(N层实体)之间需要进行交互,服务原语就是这些交互的信息,也就是接口。 要实现本层的服务,通常还需要调用下层的服务。
服务原语
在同一开放系统中,(N+1)实体向N实体请求服务时,服务用户和服务提供者之间要进行交互,交互信息称为服务原语。服务原语由服务动作和原语类型两部分组成。
一个协议中,服务原语可能有很多,但归结起来都只有4种类型:
原语 | 用途 | 方向 |
---|
请求(Request) | 用户实体要求服务做某项工作 | 源用户实体(N+1)—>源协议实体(N) | 指示(Indication) | 用户实体被告知某事件发生 | 目标协议实体(N)—>目标用户实体(N+1) | 响应(Response) | 用户实体表示对某事件的响应 | 目标用户实体(N+1)—>目标协议实体(N) | 确认(Confirm) | 用户实体收到关于它的请求的答复 | 源协议实体(N)—>源用户实体(N+1) |
服务就由服务原语及其参数进行定义。
协议文档的阅读
理解了上述的概念,一份协议栈文档的结构就比较清晰了。 一般来说,协议栈文档包括
- 协议部分,一般典型的协议包含有连接建立,数据传输交互,和断开连接的部分
- PDU=数据报文=消息结构部分,通常还包括有数据域的说明和解释
- 服务原语=服务接口部分,包括向上提供的服务原语和向下要求的服务原语
- 协议功能描述,这部分是协议要完成功能的说明和解释
- 协议的配置和参数
- 协议的错误处理
- 协议的OAM(Operation And Maintenance),主要包括排错和统计信息采集等
当然,由于每个协议作者的风格不尽相同,未必会按照上述进行编排,但我们根据上面分析结构就可以对协议进行相应的理解,从而帮助我们对协议栈进行进一步实现。
参考
下篇:网络协议实践(下)-应用层网络协议栈的典型架构
|