《网络协议分析与设计》实验报告书 实验一

一、实验目的
1.熟悉数据链路层协议,并能用PROMELA语言正确描述
2.掌握用SPIN验证协议的方法
二、实验原理
对于给定的一个使用PROMELA描述的协议系统,SPIN可以对其执行任意的模拟,也可以生成一个C代码程序,然后对该系统的正确性进行有效检验,并报告系统中出现的死锁,无效的循环,未定义的接受和标记不完全等情况。
三、实验仪器
PC机
四、实验内容
将 6.3 节描述的协议条件改为:报文和应答均会出错,且都丢失,接收方没有无限接收能力,这就是我们通常所说的实用的停等协议。请用 PROMELA 进行描述,并用 SPIN 模拟运行、一般性验证,无进展循环验证和人为加入错误进验证。
五、实验步骤及结果
1.熟悉数据链路层协议,分析并相应修改
在课本的第六章的6.3.3已经给出了简单的停等协议,这个协议的条件是报文和应答均会出错,但都不会丢失,接收方没有无限接受能力。该协议的主要过程为:发送方发送数据报,等待应答,如果是肯定应答则发送下一帧,如果是否定应答或应答帧错则重发;接收方接收报文,如果是期望的报文则发送肯定应答。否则发送否定应答,给报文加序号。我们将此协议称为RDT 3.0。
在简单的停等协议的基础上,6-5题多考虑了一种丢失的情况,可以将这种情况设为Miss,且在接受方和发送方的两个进程中添加收到Miss的情况反馈,当发送方收到Miss时,与收到Err的情况相同,都重发上一个数据;当接受方接收到Miss时,则直接跳过。
2.用PROMELA语言描述协议
1 #define MAXSEQ 5
2 mtype={Msg,Ack,Nak,Err,Miss};
3 chan SenderToReceiver=[1]of{mtype,byte,byte};
4 chan ReceiverToSender=[1]of{mtype,byte,byte};
5 proctype SENDER(chan InCh,OutCh)
6 {
7 byte SendData;
8 byte SendSeq;
9 byte ReceivedSeq;
10 SendData=0;
11 SendData=0;
12 do
13 ::skip
14 again: if
15 ::OutCh!Msg(SendData,SendSeq)
16 ::OutCh!Err(0,0)
17 ::OutCh!Miss(0,0)
18 fi;
19 if
20 ::timeout -> goto again
21 ::InCh?Miss(0,0)-> goto again
22 ::InCh?Err(0,0)-> goto again
23 ::InCh?Nak(ReceivedSeq,0)->
24 end1: goto again
25 ::InCh?Ack(ReceivedSeq,0)->
26 if
27 ::(ReceivedSeq== SendSeq)->
28 SendSeq = (SendSeq+1)%MAXSEQ;
29 SendData = (SendData+1)%MAXSEQ;
30 ::(ReceivedSeq!=SendSeq)->
31 end2: goto again
32 fi;
33 fi;
34 od;
35 }
36 proctype RECEIVER(chan InCh,OutCh)
37 {
38 byte ReceivedData;
39 byte ReceivedSeq;
40 byte ExpectedData=0;
41 byte ExpectedSeq;
42 do
43 ::InCh?Msg(ReceivedData,ReceivedSeq)->
44 if
45 ::(ReceivedSeq==ExpectedSeq)->
46 progress: ExpectedSeq=1+ExpectedSeq;
47 ExpectedData=(ExpectedData+1)%MAXSEQ;
48 if
49 ::OutCh!Miss(0,0)
50 ExpectedSeq=ExpectedSeq-1;
51 ExpectedData=(ExpectedData-1)%MAXSEQ;
52 ::OutCh!Ack(ReceivedSeq,0)
53 ::OutCh!Err(0,0)
54 ExpectedSeq=ExpectedSeq-1;
55 ExpectedData=(ExpectedData-1)%MAXSEQ;
56 fi;
57 ::(ReceivedSeq!=ExpectedSeq)
58 if
59 ::OutCh!Nak(ReceivedSeq,0)
60 ::OutCh!Err(0,0)
61 ::OutCh!Miss(0,0)
62 fi;
63 fi;
64 ::InCh?Err(0,0)
65 if
66 ::OutCh!Nak(ReceivedSeq,0)
67 ::OutCh!Err(0,0)
68 ::OutCh!Miss(0,0)
69 fi;
70 ::InCh?Miss(0,0)->skip;
71 od;
72 }
73 init
74 {
75 atomic
76 {
77 run SENDER(ReceiverToSender,SenderToReceiver);
78 run RECEIVER(SenderToReceiver,ReceiverToSender);
79 }
80 }
上述代码的主体部分是和书上的基本一致,只不过是加入MISS的情况。整体分为发送方和接收方两个进程。
在发送方进程,当发送方收到Miss时,与收到Err、收到Nak的情况相同,都goto again,重发上一个数据。
在接收方进程里,大体分为接收到正常的报文、接收有误码的报文、Err和丢失MISS。在接收到正常的报文中,如果出现ACK丢失,则和Err的情况一样,但当接收方接收到Miss时,则直接跳过。
3.用SPIN对协议进行验证
模拟运行:
在Simulate/Replay界面,选择Random,with seed,然后点击“run”,开始协议模拟,点击“stop”暂停模拟。
《网络协议分析与设计》实验报告书 实验一_第1张图片
实用停等协议的模拟运行结果如图:
《网络协议分析与设计》实验报告书 实验一_第2张图片
由于模拟运行的结果中,时序图最为直观明了,所以这里仅仅给出运行过程中产生的时序图来说明模拟运行结果,其他运行结果,例如文本方式,必须经过分析,得到的结论跟时序图是完全一样的。
输出结果如下图所示,从时序图中可以看出协议运行正确。
一般性验证:
《网络协议分析与设计》实验报告书 实验一_第3张图片
《网络协议分析与设计》实验报告书 实验一_第4张图片
在spin中,一般性验证就是选择打开verification界面,然后采取默认选项(穷举状态验证),即safety,然后点击run,开始进行一般性验证。
由图中可以看出,errors:0,说明无一般性验证错误,即该协议通过一般性验证。
从上图也可以看出(橘色框部分),发送方和接收方都在循环执行。
无进展循环验证:
验证结果如下图所示,从图中和源代码分析,可以找出验证不通过的原因是由于发送方发送错误报文后不会改变发送序号,导致发送进程中的process语句不能执行,接收方受到错误报文后也不会改变接收序号,导致接收方的process语句不能执行。但是这是协议要求的情况,是本身协议包含的内容,所以,此处的验证不通过,我们不能把它看做是协议的错误,而是在描述协议正确性要求时,process标签设置不当。
《网络协议分析与设计》实验报告书 实验一_第5张图片
人为加入错误:
为了加深对协议的理解,可人为地在协议描述中添加错误,可以将process去掉,同时添加::,这就使得发送的报文会出现乱序,验证结果。
在这题中,我将第70行的 ::InCh?Miss(0,0)->skip;改成::InCh?Miss(0,0)->goto again,即对协议进行修改,原来直接可跳过的丢失情况改为重发。经验证,出现错误。

你可能感兴趣的:(实验报告集,协议)