计算机网络课程设计模拟以太网帧封装Word文件下载.docx
《计算机网络课程设计模拟以太网帧封装Word文件下载.docx》由会员分享,可在线阅读,更多相关《计算机网络课程设计模拟以太网帧封装Word文件下载.docx(11页珍藏版)》请在冰豆网上搜索。
(3)能提高学生对所学计算机网络理论知识的理解能力;
(4)能提高学生对所学知识的实际应用能力和创新能力;
(5)提高学生的科技论文写作能力。
2.设计原理
2.1802.3标准帧结构
以太网Ethernet帧格式:
前序(P)
目的地址(SD)
源地址(SA)
长度
数据
FCS
8B
6B
2B
46~1500B
4B
1.前序字段
前序字段由7个字节的交替出现的1和0组成,设置该字段的目的是指示帧的开始并便于网络中的所有接收器均能与到达帧同步。
2.帧起始定界符字段
它可以被看作前序字段的延续。
实际上,该字段的组成方式继续使用前序字段中的格式,这个一个字节的字段的前6个比特位置由交替出现的1和0构成。
该字段的最后两个比特位置是11,这两位中断了同步模式并提醒接收后面跟随的是帧数据。
3.目的地址字段
目的地址字段确定帧的接收者。
6个字节的源地址和目的地址字段是局域网中的所有工作站必须使用同样的地址结构。
4.源地址字段
源地址字段标识发送帧的工作站。
和目前地址字段类似,源地址字段的长度六个字节。
5.长度字段
用于IEEE802.3的两字节长度字段定义了数据字段包含的字节数。
从前序到FCS字段的帧长度最小必须是64字节。
基于最小帧长为64字节和使用六字节地址字段的要求,意味着每个数据字段的最小长度为46字节。
如果传输数据少于46个字节,应将数据字段填充至46字节。
不过,填充字符的个数不包括在长度字段值中,数据字段的最大长度为1500字节。
6.数据字段
数据字段的最小长度必须为46字节以保证帧长至少为64字节,这意味着传输一字节信息也必须使用46字节的数据字段:
如果填入该该字段的信息少于46字节,该字段的其余部分也必须进行填充零。
数据字段的最大长度为1500字节。
7.校验序列字段
将计算出的CRC填入32位的FCS校验字段。
帧校验序列字段提供了一种错误检测机制,包括了地址字段、长度字段和数据字段的循环冗余校验(CRC)码。
2.2CRC的基本实现
利用CRC进行检错的过程可简单描述如下:
在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的r位监督码(CRC码),附在原始信息的后边,构成一个新的二进制码序列(共k+r位),然后发送出去。
在接收端,根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错。
这个规则在差错控制理论中称为“生成多项式”。
3.设计实现
3.1设计思路
3.1.1填充帧头部字段
在这一部分需要向输出文件写入前导码、帧前定界符、目的地址、源地址和长度字段。
写入前四个部分相对简单,而写入长度字段时需要计算输入文件的长度。
所以计算输入文件长度的方法如下:
intlength=0;
infile.seekg(0,ios:
:
end);
//将读指针移到文件末尾。
//计算指针偏移量,即为输入文件的长度
length=infile.tellg();
//创建字符指针并根据文件长度初始化
unsignedchar*data=newunsignedchar[length];
beg);
//将读指针移到文件开始。
//将文件数据读入到字符指针data中
infile.read(data,length);
//将data内容写入到输出文件中
file.write(data,length);
3.1.2填充数据字段
在数据字段中,数据字段的最小长度为46B。
如果帧的LLC数据少于46B,则应将数据字段填充至46B。
填充字符是任意的,不计入长度字段值中。
在程序中是用一下方法实现的:
//如果输入文件长度不足46B,则用补足46B
if(length<
46)
{
for(intj=length;
j<
46;
j++)
file.put(char(0x00));
}
3.1.3计算填充CRC
帧封装的最后一步就是对数据进行校验,并将校验结果记入帧校验字段。
本程序中实现的是CRC-8校验算法,即多项式G(x)=x^8+x^2+x+1,方法如下所示:
file.put(char(0x00));
//数据后补1B的0,用于crc计算file.seekg(8,ios:
//将读指针指向目的地址字段,从此处开始CRC计算
unsignedcharch;
//ch用来保存读入的字符。
unsignedcharcrc=char(0x00);
//余数初始值为。
unsignedcharcrc=0;
//初始余数为0
while(total--)
{
unsignedchartemp;
file.get(temp);
//读1B的数据
//多项式G(x)=x^8+x^2+x+1即以下模拟数据除以100000111的二进制除法过程
for(unsignedchari=(unsignedchar)0x80;
i>
0;
>
=1)
{
if(crc&
0x80)
{
crc<
<
=1;
if(temp&
i)crc^=0x01;
//将输入数据相应位的值递补到余数末位
crc^=0x07;
//进行除法运算(即减去除数的低8位:
00000111)
}
else
}
}
3.2程序流程图
3.2.1程序流程图
3.2.2CRC计算流程图
4.程序源代码(主要代码)
CStringstr;
voidCEx3Dlg:
OnButton2()
{
CStringfilter;
filter="
文本文件(*.txt)|*.txt|c++文件(*.h,*.cpp)|*.h,*.cpp||"
;
CFileDialogdlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,filter);
if(dlg.DoModal()==IDOK)
str=dlg.GetPathName();
//AfxMessageBox(str);
MessageBox("
文件选择成功"
);
//intnIndex=m_edit.AddString(str);
//m_edit.SetItemDataPtr(nIndex,0);
}
OnButton1()
fstreamfile;
//打开指定输出文件,读写方式为以二进制方式可读可写,如文件存在则清除其内容
file.open("
D:
\\out.txt"
ios:
in|ios:
out|ios:
binary|ios:
trunc);
for(inti=0;
i<
7;
i++)file.put(char(0xaa));
//写入7B前导码
file.put(char(0xab));
//写入1B帧前界定符
longpCrcs=file.tellp();
//获得当前文件指定指针位置,计算CRC时从这里开始
chardst_addr[6]={char(0xff),char(0xff),char(0xe4),char(0x86),char(0x30),char(0xd0)};
file.write(dst_addr,sizeof(dst_addr));
//写入6B目的地址
charsrc_addr[6]={char(0xff),char(0xff),char(0x80),char(0x1a),char(0xe6),char(0x09)};
file.write(src_addr,sizeof(src_addr));
//写入6B源地址
ifstreaminfile;
infile.open(str,ios:
binary);
infile.seekg(0,ios:
//将文件读指针移到末尾
shortlength=(short)infile.tellg();
//获得位置偏移量,即为输入文件长度
file.put(char(length/256));
//将该长度写入数据长度字段(2B)
file.put(char(length%256));
char*data=newchar[length];
infile.read(data,length);
//从输入文件中读出所有数据至data中
file.write(data,length);
//将data中数据写入输出文件
infile.close();
deletedata;
if(length<
46)
for(inti=0;
46-length;
i++)
file.put(char(0x00));
//数据字段不足46B的部分用0填充
longpCrc=file.tellp();
//获得当前位置,计算后的CRC码将写到这个位置
//数据后补1B的0,用于crc计算
shorttotal=short(file.tellp())-(short)pCrcs;
//需要进行计算的数据长度
file.seekg(pCrcs,ios:
//将读指针指向目的地址字段,从这里开始crc计算
//初始余数为0
//读1B的数据
//多项式G(x)=x^8+x^2+x+1即以下模拟数据除以100000111的二进制除法过程
if(temp&
//将输入数据相应位的值递补到余数末位
crc^=0x07;
//进行除法运算(即减去除数的低8位: