数据帧封装实验文档文档格式.docx

上传人:b****6 文档编号:17724389 上传时间:2022-12-08 格式:DOCX 页数:10 大小:98.66KB
下载 相关 举报
数据帧封装实验文档文档格式.docx_第1页
第1页 / 共10页
数据帧封装实验文档文档格式.docx_第2页
第2页 / 共10页
数据帧封装实验文档文档格式.docx_第3页
第3页 / 共10页
数据帧封装实验文档文档格式.docx_第4页
第4页 / 共10页
数据帧封装实验文档文档格式.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

数据帧封装实验文档文档格式.docx

《数据帧封装实验文档文档格式.docx》由会员分享,可在线阅读,更多相关《数据帧封装实验文档文档格式.docx(10页珍藏版)》请在冰豆网上搜索。

数据帧封装实验文档文档格式.docx

目的地址

源地址

长度字段

数据字段

校验字段

7B

1B

(2/6B)

(2B)

(长度可变)

(4B)

(1)前导码与帧前定界符字段

前导码由56位(7B)的10101010…101010位序列组成。

帧前定界符可以视为前导码的延续。

1B的帧前定界符结构为10101011。

如果将前导码与帧前定界符一起看,那么在62位101010…1010位序列之后出现11。

在11之后是Ethernet的目的地址字段。

前导码与帧前定界符主要是保证接收同步,这8B接收后不需要保留,也不记入帧头长度中。

(2)目的地址和源地址

目的地址(DA)与源地址(SA)分别表示帧的接收结点地址与发送结点的硬件地址。

在Ethernet帧中,目的地址和源地址字段长度可以是2B或6B。

目前的Ethernet都使用6B(即(48位)长度的地址。

Ethernet帧的地址可以是单播地址(unicastaddress)、多播地址(multicastadderss)与广播地址(broadcastaddress),目的地址的第一位为0表示单播地址,为1表示多播地址,目的地址为全1则表示广播地址。

(3)长度字段

802.3标准中的帧用2B定义数据字段包含的字节数。

协议规定,帧数据的最小长度为46B,最大长度为1500H。

设置最小帧长度的目的是使每个接收结点能够有足够的时间检测到冲突。

(4)数据字段

帧数据字段的最小长度为46B,最大为1500B。

如果帧的LLC数据少于46B,则应将数据字段填充至46B。

设置最小帧长度的目的是使每个接收点能够由足够的时间检测到冲突。

填充字符是任意的,不计入长度字段值中。

(5)校验字段

帧校验字段(FCS)彩位的CRC校验。

校验的范围包括目的地址字段、源地址字段、长度字段、LLC数据字段。

在这个程序实现中,彩位的CRC校验。

CRC校验的生成多项式为:

某些帧结构中还会包括帧类型字段,用来识别此帧所承载的数据的类型。

当一个帧到达指定的计算机时,操作系统根据帧类型决定用哪个协议软件模块对它进行处理。

自识别帧的主要优点是,可以在同一物理网络中使用多个协议而互不干扰。

1.2CRC校验

循环冗余编码(CyclicRedundanryCode,CRC)是一种重要的线性分组码、编码和解码方法,具有简单、检错和纠错能力强等特点,在通信领域广泛地用于实现差错控制。

利用CRC进行检错的过程可简单描述如下:

在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的r位监督码(CRC码),附在原始信息的后边,构成一个新的二进制码序列(共k+r位),然后发送出去。

在接收端,根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错。

这个规则在差错控制理论中称为“生成多项式”。

(1)CRC编码的代数学原理

在代数编码理论中,将一个码组表示为一个多项式,码组中的各码元作为多项式的系数。

例如,1100101表示为

,即

设编码前的原始信息多项式为P(x),P(x)的最高幂次加1等于k;

生成多项式为G(x),G(x)的最高幂次等于r;

CRC多项式为R(x);

编码后的带CRC的信息多项式为T(x)。

发送方编码的方法是:

将P(x)乘以

(即对应的二进制码序列左移r位),再除以G(x),即用二进制的模2运算进行

乘M的运算,得余式即为R(x)。

用模2运算进行加法时不进位,如,1111+1010=0101。

减法和加法一样,按加法规则计算。

用公式可以表示为:

[2]

接收方解码的方法是:

将T(x)除以G(x),如果余数为0,则说明传输中无错误发生,否则说明传输有误。

例如,信息码为1100,生成多项式为1011,即

,则可以用以下方法计算CRC:

即R(x)=x。

注意到G(x)的最高幂次r=3,得出CRC为010。

如果用竖式除法,计算过程为:

因此,

,即1100000+010=1100010。

如果传输无误,

无余式。

看一下上面的竖式除法,如果被除数是1100010,显然在商第3个1时,就能除尽。

(2)CRC的基本实现

以CRC-8

为例(如图1.1所示),它由多个移位寄存器和加法器组成。

编码、解码前将各寄存器初始化为0,输入位作为最右边异或操作的输入之一。

三个寄存器上的移位操作同时进行,均为左移一位,左边寄存器的最左一位作为三个异或操作的输入之一。

每次移位时,最右边的寄存器内容作为中间异或的输入之一,中间的寄存器的内容作为最左边异或操作输入之一,各个异或操作的结果作为与它左边那个寄存器的移入位。

重复心目步骤,每输入一个位就做一次移位操作,直到输入了所有要计算的数据为止。

这时,这个寄存器组中的数据就是CRC-8的结果。

图1.1CRC基本实现

CRC的工作原理是,CRC在发送端编码和接收端校验时,都可以利用事先约定的生成多项式G(x)来得到,K位要发送的信息位可对应于一个(k-1)次多项式K(x),r位冗余位则对应于(r-1)次多项式R(x),由r位冗余位组成的n=k+r位码字则对应于一个(n-1)次多项式

(3)循环冗余校验码的特点

CRC校验码的检错能力很强,不仅能检查出离散错误,还能检查出突发错误。

CRC校验码具有以下检错能力:

CRC校验码可检测出所有单个错误。

CRC校验码可检测出所有奇数位错误。

CRC校验码可检测出所有双位的错误。

CRC校验码可检测出所有小于、等于校验位长度的突发错误。

CRC校验码可以

的概率检测出长度为(K+1)位的突发错误。

2设计思路

程序共分三个部分:

填充帧头部字段,填充数据字段,计算CRC校验码并填充。

填充帧头部字段及数据字段。

由于帧封装要求输入文件数据最大长度为1500B,那么当输入文件长度超过1500B时要进行分割,以每1500B为单位进行帧封装。

这个程序就是初步实现了这一功能。

2.1数据填充

在这一部分需要向输出文件写入前导码、帧前定界符、目的地址、源地址和长度字段。

写入前四个部分十分简单,而写入长度字段时需要计算输入文件的长度。

2.2CRC校验码的计算

帧封装的最后一步就是对数据进行校验,并将校验结果记入帧校验字段。

本程序中实现的是CRC-8校验算法,由于CRC-8的生成多项式为

即100000111,则生成的CRC校验码就是8位,所以CRC-8校验码的计算过程就是逐位填入并进行异或运算的过程:

先构造一个8位的寄存器crc,初始值为0,数据依次移入crc的0位,同时crc的7位移出。

当移出的数据为1时,crc才和0x07进行异或运算;

移出的数据为0时,不做运算。

实现的程序为:

unsignedcharch;

//ch用来保存读入的字符。

unsignedcharcrc=char(0x00);

//余数初始值为0。

while

(1){//进行CRC计算

outfile.get(ch);

if(ch==0xff)//判断是否到了文件结尾,如果是,则退出循环。

break;

for(j=0;

j<

8;

j++){//对入读入的字符的8位分别处理。

if((crc&

(0x80))==0x80){//当前余数最高位为1,需要进行除法运算。

crc=(crc<

<

1)&

(0xff);

//crc左移1位,最低位补0。

crc=crc|((ch&

0x80)>

>

7);

//将输入数据相应的值递补到余数末位。

crc=crc^(0x07);

//进行除法运算,即与除数的低8位相异或。

}else{//当前余数的最高位为0,不需要进行除法运算。

//将输入数据相应位的值递补到余数末位。

}

ch=ch<

1;

//读到的字符左移1位,使数据下一位作为输入位。

}

}

3程序流程图

程序流程图如图所示。

4程序代码

#include<

iostream.h>

fstream.h>

stdlib.h>

stdio.h>

voidmain(intargc,char*argv[]){

//如果输入命令行不正确,则输出提示后退出。

if(argc!

=3){

printf("

请按以下格式输入:

framerinputfileoutputfile\n"

);

exit(0);

}

//打开指定的输入文件,以二进制方式打开并可读

ifstreaminfile(argv[1],ios:

:

in|ios:

binary,0);

intlength=0,i=1,j=0;

infile.seekg(0,ios:

end);

//将读指针移到文件末尾。

length=infile.tellg();

//计算指针偏移量,即为输入文件的长度。

fstreamoutfile(argv[2],ios:

out|ios:

binary|ios:

trunc,0);

//打开输出文件

for(inttemplength=0;

templength<

length;

templength+=1500){//每1500个字符构成一个循环

7;

j++){

outfile.put((char)0xaa);

outfile.put((char)0xab);

//写入7B的前导码和1B的帧前定界符。

chardes_add[]={char(0xB1),char(0xB2),char(0xB3),char(0xB4),char(0xB5),char(0xB6)};

outfile.write(des_add,6);

//写入6B的目的地址。

charsor_add[]={char(0xA1),char(0xA2),char(0xA3),char(0xA4),char(0xA5),char(0xA6)};

outfile.write(sor_add,6);

//写入6B的源地址。

unsignedchardata[1500];

//创建字符数组。

infile.seekg(templength,ios:

beg);

//将读指针移到文件指定地方。

infile.read(data,1500);

//将文件数据读入到字符指针data中。

intnumber=infile.gcount();

//获取实际读得的数据数

outfile.put(char(number>

8));

outfile.put(char(number&

0xff));

//将读到的数据数写入到输出文件中。

outfile.write(data,number);

//将data内容写入到输出文件中。

//如果输入文件长度不足46B,则用0补足46B。

if(number<

46){

for(intj=number;

46;

j++)

outfile.put(char(0x00));

outfile.put(char(0x00));

outfile.seekg(8,ios:

//将读指针指向目的地址字段,从此处开始CRC计算

unsignedcharch;

unsignedcharcrc=char(0x00);

while

(1){//进行CRC计算

outfile.get(ch);

if(ch==0xff)//判断是否到了文件结尾,如果是,则退出循环。

break;

for(j=0;

if((crc&

crc=(crc<

crc=crc|((ch&

crc=crc^(0x07);

}else{//当前余数的最高位为0,不需要进行除法运算。

}

ch=ch<

outfile.clear();

outfile.seekp(-1,ios:

//将写指针移到输出文件的最后一个字节。

outfile.put(crc);

//写入crc码。

第%d帧CRC:

%X\n"

i++,crc);

outfile.close();

//关闭输出文件

infile.close();

//关闭输入文件

cout<

endl<

"

源文件:

"

argv[1]<

,封装之后生成帧文件:

argv[2]<

OK"

endl;

5实验结果

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 农学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1