1. 为什么建立UML模型范例
作为统一建模语言,UML可以帮助我们对很多业务、技术的知识进行梳理,从多个视角描述清楚,帮助读者理解。另外因为UML的建模首先来自于软件建模的需求,所以UML的模型很容易转换为软件的设计,这对于软件开发者来说是一个天生的福利。
现在UML对于IT技术有关的建模已经比较成功,例如:
用类图建模 数据模型、程序结构。
用活动图建模业务流程、程序流程和运算过程等等。
用顺序图建模人员交互、程序模块交互等等。
用状态图建模控制对象的状态逻辑。
但是一个完整的应用,最重要的往往是专业性强的领域知识的建模。而这方面,可以公开看到的UML范例却不多,这也就造成了UML建模的价值还没有被充分的挖掘出来。
所以我们尝试采用UML对各个领域的专业知识建模,期望能够让大家看到逻辑建模的重要性,以及在逻辑建模方面以面向对象思想为核心的UML建模的强大表达力。进而更多的采用UML提高描述、分析和设计能力。
虽然UML对逻辑建模具有很大的表达能力,但是各个专业领域自身、以及人们自发的描述方式也是非常重要的,而且一般是各种专业知识的首要表达方式。所以UML的建模不应该成为已有描述形式的颠覆者,而更应该是对已有描述的梳理,以更简洁、更加精确、更加抽象的方式进行逻辑化描述。这样可以对知识进行多个维度、多个层次的更加充分的挖掘和展示。因为我们这里主要关注UML的建模,但是也不想损失已有的知识描述,所以在UML之前的各种已有的知识的描述和建模方式,我们这里称之为
“原生图”。
所以我们对专业知识的建模采用2种方式:
原生图:采用被建模领域的常见图示,可以是专业图,也可以是一些形象的示意图。
UML图:采用UML建模,重点是逻辑的描述,更强调建模的简洁性和清晰度。
为了更加充分的描述被建模对象,这里采用4个视角进行建模:
结构视角:描述事物的构成和关系,是一种静态视图。
过程视角:描述一个事物的行为过程,是一种动态视图。
数据视角:描述行为过程中传递的数据,数据结构是静态视图, 数据的传递是一个动态视图。
状态视角:描述各种对象和行为的状态变化,状态的数据结构定义,属于静态视图,状态的转换过程,是一种动态视图。
本文采用UML模型对TCP协议进行建模。主要涉及4个视图:
1. 结构视图:描述该协议的网络通信相关的节点和链接。
2. 过程视图:描述基于该协议的网络通信的过程。
3. 数据视图:描述通信相关的数据结构和关系。
4. 状态视图:描述通信过程中的对象状态。
2. TCP/IP协议简介
TCP 协议是通信网络传输层的网络通信协议。为了充分的理解TCP按照TCP/IP的5层协议结构,我们看看各层通信协议的职责,如下图所示:
TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议)是指能够在多个不同网络间实现信息传输的协议簇。TCP/IP协议不仅仅指的是TCP
和IP两个协议,而是指一个由FTP、SMTP、TCP、UDP、IP等协议构成的协议簇, 只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP/IP协议。
TCP/IP五层模型说明
层 |
职责 |
应用层 |
应用程序层是需要网络通信的应用程序所在的位置。这些应用程序的示例包括电子邮件客户端和Web浏览器。这些应用程序使用传输层发送请求以连接到远程主机。
|
传输层 |
在传输层建立在不同主机上运行的应用程序之间的连接。它使用TCP进行可靠连接,使用UDP进行快速连接。它通过为其分配port号来跟踪在其上方的应用程序中运行的进程,并使用网络层访问TCP
/ IP网络。 |
网络层 |
该网络层负责创建在整个网络中的数据包。它使用IP地址来识别数据包的源和目的地。 |
数据链路层 |
该数据链路层负责创建跨网络传输的帧。这些帧封装了数据包,并使用MAC地址来标识源和目的地。
|
物理层 |
所述物理层编码和解码数据链路层的一帧中的bit,它包括收发器,可以在网络上发生和接收信号。
|
通信过程中最重要的数据就是在各个通信协议层次传递的数据。如下是一个要发送的消息通过各个网络协议层的过程中被逐步添加相应协议信息的示意图:
较高的层将信息传递给较低的层。每一层都将被称为header的信息添加到传递给它的数据中。此header包含图层执行其工作所需的信息。我们将从应用程序层开始。
我们更关注各个层次数据的逐步累加过程,为了让表达累加过程中数据结构的变化,采用UML的类图,对各个层次的数据结构进行建模如下:
各个网络通信层次对消息的处理过程采用UML的活动图描述其中的数据流如下:
活动图描述 |
过程的文本描述 |
|
应用程序层生成一条消息。在这种情况下,特定的应用程序是请求网页下载的Web浏览器。然后,此消息将发送到传输层。
传输层添加了TCP 或者UDP 的header,其中包括源port和目标port地址。其他信息(如用于TCP的数据包序列号)也将添加到header中。如果使用TCP,则由传输层生成的数据称为段(segment),如果使用UDP,则称为数据报(Datagram)。然后将该段发送到网络层。
网络层添加了包含源IP地址和目标IP地址的header以生成数据包(Packet)。然后将此数据包发送到数据链路层。
数据链路层添加包含MAC地址信息的header以创建帧(Frame)。然后,将该帧发送到物理层以传输比特码。 |
活动图描述 |
|
过程的文本描述 |
应用程序层生成一条消息。在这种情况下,特定的应用程序是请求网页下载的Web浏览器。然后,此消息将发送到传输层。
传输层添加了TCP 或者UDP 的header,其中包括源port和目标port地址。其他信息(如用于TCP的数据包序列号)也将添加到header中。如果使用TCP,则由传输层生成的数据称为段(segment),如果使用UDP,则称为数据报(Datagram)。然后将该段发送到网络层。
网络层添加了包含源IP地址和目标IP地址的header以生成数据包(Packet)。然后将此数据包发送到数据链路层。
数据链路层添加包含MAC地址信息的header以创建帧(Frame)。然后,将该帧发送到物理层以传输比特码。
|
3. UML建模图例
下面采用UML的4个视图建模TCP通信协议。
3.1 结构视图
主要描述TCP协议的网络通信相关的网络节点和连接,采用UML的复合结构图建模如下:
3.2 过程视图
过程视图主要描述2各层次:
整个网络通信的过程
TCP传输的过程
TCP通信过程
建立连接
通过三次握手(3个消息)建立客户端和服务端的连接:
1. 客户端发出建立连接请求,
2. 服务端响应
3. 客户端确认收到响应
过程的文本描述 |
顺序图描述 |
段1 :客户端发送一个连接请求消息
SYN报文说明:在TCP头部的SYN位字段置位的TCP/IP数据包,并指明自己想要连接的port号和它的客户端初始序列号(记为ISN,图中ISN=x)。
段2:服务端响应连接请求消息
服务端收到请求后,也发送自己的SYN报文段作为响应,并包含了它的初始序列号(ISN(s)=y)。此外,为了确认客户端的SYN,SYN数据加1后作为返回的ACK数值。因此,每发送一个SYN,序列号就会自动加1。、
段3:客户端发送确认收到响应的消息
为了确认服务器端的SYN,客户端将ISN(s)的数值加1后作为返回的ACK数值。这称为段3。
|
|
顺序图描述 |
|
过程的文本描述 |
段1
:客户端发送一个连接请求消息
SYN报文说明:在TCP头部的SYN位字段置位的TCP/IP数据包,并指明自己想要连接的port号和它的客户端初始序列号(记为ISN,图中ISN=x)。
段2:服务端响应连接请求消息
服务端收到请求后,也发送自己的SYN报文段作为响应,并包含了它的初始序列号(ISN(s)=y)。此外,为了确认客户端的SYN,SYN数据加1后作为返回的ACK数值。因此,每发送一个SYN,序列号就会自动加1。、
段3:客户端发送确认收到响应的消息
为了确认服务器端的SYN,客户端将ISN(s)的数值加1后作为返回的ACK数值。这称为段3。
|
传输数据
如下是传输数据的图示:
关闭连接
通过四次握手(4个消息)关闭客户端和服务端的连接:
1. 客户端发出关闭请求
2. 服务端确认
3. 服务端发出关闭请求
4. 客户端确认
过程的文本描述 |
顺序图描述 |
1. 主动关闭者发送一个FIN,指明接收者希望看到的自己当前的序列号。目的是告诉被动关闭方,我要关闭连接了。
2. 被动关闭方收到 FIN包后,发送一个ACK给对方,将K的数值加1作为响应的ACK值,以标识该ACK对应的FIN
。
3. 被动关闭方发送一个FIN,用来告诉对方,我也可以关闭连接了。为了标识这是自己发起的,有一个表示位seq
=q,为了标识该FIN对应的主动关闭方发起的FIN,会有标识符ack = p+1;
4. 主动关闭方收到 FIN后,发送和一个ACK给对方,告知确认关闭,用一个标识位ack =q+1标识对应的请求。
|
|
顺序图描述 |
|
过程的文本描述 |
1.
主动关闭者发送一个FIN,指明接收者希望看到的自己当前的序列号。目的是告诉被动关闭方,我要关闭连接了。
2. 被动关闭方收到 FIN包后,发送一个ACK给对方,将K的数值加1作为响应的ACK值,以标识该ACK对应的FIN
。
3. 被动关闭方发送一个FIN,用来告诉对方,我也可以关闭连接了。为了标识这是自己发起的,有一个表示位seq
=q,为了标识该FIN对应的主动关闭方发起的FIN,会有标识符ack = p+1;
4. 主动关闭方收到 FIN后,发送和一个ACK给对方,告知确认关闭,用一个标识位ack
=q+1标识对应的请求。
|
如下是来自于一篇网络文章的关闭连接的过程描述:
第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但此时主动关闭方还可以接受数据。
第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。
第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。
第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。 |
3.3 数据视图
一个具体的TCP报文结构如下图所示:
可以用UML的类图对报文结构进行建模,图示如下:
这个类图对结构的关系描述的更加清晰,也符合开发工程师的结构化需要。当然也比较抽象,应该结合原生图进行理解才好。
3.4 状态视图
通信协议因为存在状态变迁,所以一般采用状态图建模协议的状态机。下图来自于一篇网络是常见的TCP协议状态机(来自于一篇网络文章):
TCP状态及其描述如下表。
状态 |
描述 |
LISTEN |
等待来自远程TCP应用程序的请求 |
SYN_SENT |
发送连接请求后等待来自远程端点的确认。TCP第一次握手后客户端所处的状态 |
SYN-RECEIVED |
该端点已经接收到连接请求并发送确认。
该端点正在等待最终确认。TCP第二次握手后服务端所处的状态 |
ESTABLISHED |
代表连接已经建立起来了。这是连接数据传输阶段的正常状态 |
FIN_WAIT_1 |
等待来自远程TCP的终止连接请求或终止请求的确认 |
FIN_WAIT_2 |
在此端点发送终止连接请求后,等待来自远程TCP的连接终止请求 |
CLOSE_WAIT |
该端点已经收到来自远程端点的关闭请求,此TCP正在等待本地应用程序的连接终止请求 |
CLOSING |
等待来自远程TCP的连接终止请求确认 |
LAST_ACK |
等待先前发送到远程TCP的连接终止请求的确认 |
TIME_WAIT |
等待足够的时间来确保远程TCP接收到其连接终止请求的确认 |
这个状态图涉及到了客户端、服务端、网络连接多个对象,所以看起来一头雾水,很难理解。这样的图示对于用户是不友好的,所以有必要用UML的状态图改进一下。
状态图的建模首先应该识别持有状态的对象,然后再建立它的状态图,TCP网络通信过程实际上涉及到了3个对象:
客户端Client,
服务端Host,
网络连接Connection 。
他们分别有各自的状态图,下面基于TCP的通信过程,对三个对象的状态分别进行建模。
Client节点的状态 |
Host的状态 |
|
|
Connection的状态如下
这样看起来和通信过程完全映射,好理解多了。
希望您读了此文后有所受益。如果您对UML感兴趣,欢迎阅读更多文章:
如果您希望了解更多信息:
作者简介:
俎涛,火龙果软件工程创始人,2001年创立了火龙果软件工程,2004年创立了IBM Rational用户组。1998年,曾作为骨干参与国家重点研究课题《面向特定领域基于组件的软件复用》,有幸比较深入的学习和使用的UML进行领域建模、提炼可复用组件和架构。在后来的研发项目中,一直采用模型进行分析设计,积累了一些心得和经验。20年来一直专注于MBSE,熟悉
UML、Sys ML、ArchiMate、BPMN、UPDM、DataModel等建模语言和规范,在以往的经历中,最大的感触是汇聚了很多精英人才的软件工程和系统工程领域居然几十年都是一种凌乱迷蒙的状态,从自己的经历所得,觉得清晰的模型,才是拨开工程迷雾的关键所在,所以不断研究和应用各种建模技术,并从自己的工程实践中提炼经验,形成对于自己可持续的方法论,例如《MBSE
从方法到实践指南》 《基于模型的三维研发管理》 《基于模型的需求管理》 《模型驱动的架构设计》
《基于模型的质量管理》 《基于模型的人员能力管理》 《iProcess过程改进方法》,目前正在作为产品经理和架构师,进行MBSE(基于模型的系统工程)平台的研发,希望建立要给基于模型的工程解决方案,后续会不断写些文章,希望能给同行一些借鉴。 |
后记
希望您读了此文后有所受益。
如果您有经验乐于分享,欢迎投稿给我们。
如果您对我们的培训、咨询和工具感兴趣:
|