Ethernet帧结构解析汇报文档格式.docx

上传人:b****7 文档编号:22061355 上传时间:2023-02-02 格式:DOCX 页数:17 大小:199.60KB
下载 相关 举报
Ethernet帧结构解析汇报文档格式.docx_第1页
第1页 / 共17页
Ethernet帧结构解析汇报文档格式.docx_第2页
第2页 / 共17页
Ethernet帧结构解析汇报文档格式.docx_第3页
第3页 / 共17页
Ethernet帧结构解析汇报文档格式.docx_第4页
第4页 / 共17页
Ethernet帧结构解析汇报文档格式.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

Ethernet帧结构解析汇报文档格式.docx

《Ethernet帧结构解析汇报文档格式.docx》由会员分享,可在线阅读,更多相关《Ethernet帧结构解析汇报文档格式.docx(17页珍藏版)》请在冰豆网上搜索。

Ethernet帧结构解析汇报文档格式.docx

所幸的是,后者定义的有效长度值与前者定义的有效类型值无一相同,这样就容易区分两种帧格式

2程序流程图:

三.详细设计:

1.CRC校验部分设计:

为了对以太网帧的对错进行检验,需要设计CRC校验部分。

采用以为相与的方式对帧的首部相继作8位CRC校验

输入参数:

chCurrByte低8位数据有效,记录了上一次CRC校验的余数

chNextByte低8位数据有效,记录了本次要继续校验的一个字节

传出参数:

chCurrByte低8位数据有效,记录了本次CRC校验的余数

voidcheckCRC(int&

chCurrByte,intchNextByte)

{

//CRC循环:

每次调用进行8次循环,处理一个字节的数据。

for(intnMask=0x80;

nMask>

0;

>

=1)

if((chCurrByte&

0x80)!

=0)//首位为1:

移位,并进行异或运算

{

chCurrByte<

<

=1;

//移一位

if((chNextByte&

nMask)!

=0)//补一位

{

chCurrByte|=1;

}

chCurrByte^=7;

//首位已经移出,仅对低8位进行异或运算,7的二进制为0000,0111

else//首位为0,只移位,不进行异或运算

}

2.部分变量的声明:

intnSN=1;

//帧序号

intnCheck=0;

//校验码

intnCurrDataOffset=22;

//帧头偏移量

intnCurrDataLength=0;

//数据字段长度

boolbParseCont=true;

//是否继续对输入文件进行解析

intnFileEnd=0;

//输入文件的长度

3.计算数据段的长度:

nCurrDataLength=

bParseCont?

//是否到达文件末尾

(file.tellg()-8-1-nCurrDataOffset):

//没到文件末尾:

下一帧头位置-前导码和定界符长度-CRC校验码长度-数据字段起始位置

(file.tellg()-1-nCurrDataOffset);

//已到达文件末尾:

文件末尾位置-CRC校验码长度-数据字段起始位置

4.主函数的设计:

voidmain(intargc,char*argv[])

//检测命令行参数的正确性

if(argc!

=2)

cout<

"

请以帧封装包文件为参数重新执行程序"

<

endl;

exit(0);

//检测输入文件是否存在,并可以按所需的权限和方式打开

ifstreamfile(argv[1],ios:

:

in|ios:

binary|ios:

nocreate);

if(!

file.is_open())

无法打开帧封装包文件,请检查文件是否存在并且未损坏"

//变量声明及初始化

//计算输入文件的长度

file.seekg(0,ios:

end);

//把文件指针移到文件的末尾

nFileEnd=file.tellg();

//取得输入文件的长度

beg);

//文件指针位置初始化

cout.fill('

0'

);

//显示初始化

cout.setf(ios:

uppercase);

//以大写字母输出

//定位到输入文件中的第一个有效帧

//从文件头开始,找到第一个连续的“AA-AA-AA-AA-AA-AA-AA-AB”

while(true)

{

for(intj=0;

j<

7;

j++)//找7个连续的0xaa

if(file.tellg()>

=nFileEnd)//安全性检测

cout<

"

没有找到合法的帧"

endl;

file.close();

//看当前字符是不是0xaa,如果不是,则重新寻找7个连续的0xaa

if(file.get()!

=0xaa)

j=-1;

if(file.get()==0xab)//判断7个连续的0xaa之后是否为0xab

break;

//将数据字段偏移量定位在上述二进制串之后14字节处,并准备进入解析阶段

nCurrDataOffset=file.tellg()+14;

file.seekg(-8,ios:

cur);

//主控循环

while(bParseCont)//当仍然可以继续解析输入文件时,继续解析

//检测剩余文件是否可能包含完整帧头

if(file.tellg()+14>

nFileEnd)

endl<

没有找到完整帧头,解析终止"

intc;

//读入字节

inti=0;

//循环控制变量

intEtherType=0;

//由帧中读出的类型字段

boolbAccept=true;

//是否接受该帧

//输出帧的序号

endl<

序号:

\t\t"

nSN;

//输出前导码,只输出,不校验

前导码:

\t"

;

for(i=0;

i<

i++)//输出格式为:

AAAAAAAAAAAAAA

cout.width

(2);

hex<

file.get()<

dec<

//输出帧前定界符,只输出,不校验

帧前定界符:

//输出格式为:

AB

file.get();

//输出目的地址,并校验

目的地址:

6;

xx-xx-xx-xx-xx-xx

c=file.get();

c<

(i==5?

:

-"

if(i==0)//第一个字节,作为“余数”等待下一个bit

nCheck=c;

else//开始校验

checkCRC(nCheck,c);

//输出源地址,并校验

源地址:

//继续校验

//输出类型字段,并校验

类型字段:

//输出类型字段的高8位

//CRC校验

EtherType=c;

//输出类型字段的低8位

c;

checkCRC(nCheck,c);

EtherType<

=8;

//转换成主机格式

EtherType|=c;

//定位下一个帧,以确定当前帧的结束位置

while(bParseCont)

for(inti=0;

i++)//找下一个连续的7个0xaa

=nFileEnd)//到文件末尾,退出循环

bParseCont=false;

=0xaa)

i=-1;

//如果直到文件结束仍没找到上述比特串,将终止主控循环的标记bParseCont置为true

bParseCont=bParseCont&

&

(file.tellg()<

nFileEnd);

//判断7个连续的0xaa之后是否为0xab

if(bParseCont&

file.get()==0xab)

//计算数据字段的长度

nCurrDataLength=

bParseCont?

(file.tellg()-8-1-nCurrDataOffset):

(file.tellg()-1-nCurrDataOffset);

//以文本格式数据字段,并校验

数据字段:

unsignedchar*pData=newunsignedchar[nCurrDataLength];

//创建缓冲区

file.seekg(bParseCont?

(-8-1-nCurrDataLength):

(-1-nCurrDataLength),ios:

file.read(pData,nCurrDataLength);

//读入数据字段

intnCount=50;

//每行的基本字符数量

nCurrDataLength;

i++)//输出数据字段文本

nCount--;

pData[i];

//字符输出

checkCRC(nCheck,(int)pData[i]);

if(nCount<

0)//换行处理

//将行尾的单词写完整

if(pData[i]=='

'

nCount=50;

//处理过长的行尾单词:

换行并使用连字符

-10)

delete[]pData;

//释放缓冲区空间

//输出CRC校验码,如果CRC校验有误,则输出正确的CRC校验码

CRC校验"

//读入CRC校验码

intnTmpCRC=nCheck;

//最后一步校验

if((nCheck&

0xff)==0)//CRC校验无误

(正确):

else//CRC校验有误

(错误):

checkCRC(nTmpCRC,0);

//计算正确的CRC校验码

\t应为:

(nTmpCRC&

0xff);

bAccept=false;

//将帧的接收标记置为false

//如果数据字段长度不足46字节或数据字段长度超过1500字节,则将帧的接收标记置为false

if(nCurrDataLength<

46||nCurrDataLength>

1500)

//输出帧的接收状态

状态:

(bAccept?

Accept"

Discard"

)<

nSN++;

//帧序号加1

nCurrDataOffset=file.tellg()+22;

//将数据字段偏移量更新为下一帧的帧头结束位置

//关闭输入文件

file.close();

四.运行结果:

五.简明用户手册:

用户需将源程序在VC++6.0下运行成功后,将实验1.EXE放在DOS下运行,运行的同时需要输入位置参数,本例用的位置参数为input,回车即可。

六.实验总结:

这次试验,充分运用了所学的计算机网络知识,设计出了如何解析以太网帧,从而更加深刻的了解到了以太网帧的结构及其的相关问题。

其实通过这些最近的实验觉得最重要一点就是:

我们一定要自己动手,这样才能真正的学到东西。

书本知识固然重要,但我们更要学会将书本知识应用到实际的工作中。

实践中才会发现错误,也才能改进,才能达到学习的最终目的。

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

当前位置:首页 > 解决方案 > 其它

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

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