兰州理工大学以太网帧的封装与成帧设计解析.docx
- 文档编号:3366131
- 上传时间:2022-11-22
- 格式:DOCX
- 页数:20
- 大小:192.73KB
兰州理工大学以太网帧的封装与成帧设计解析.docx
《兰州理工大学以太网帧的封装与成帧设计解析.docx》由会员分享,可在线阅读,更多相关《兰州理工大学以太网帧的封装与成帧设计解析.docx(20页珍藏版)》请在冰豆网上搜索。
兰州理工大学以太网帧的封装与成帧设计解析
*******************
实践教学
*******************
兰州理工大学
计算机与通信学院
2015年秋季学期
计算机通信课程设计
题目:
以太网帧的封装与成帧设计
专业班级:
姓名:
学号:
指导教师:
王慧琴
成绩:
摘要
本次课程设计应用了计算机通信技术中有关于以太网的帧结构的知识,应用数据链路层的相关知识,通过对帧中固定的前导码,源地址,目的地址等写入,在处理数据字段之后与其一起进行封装,构造成一个具体的帧。
在VC6.0中采用与封装与解析数据包相关的代码编写“工程”,其中利用windsock库函数进行封装与解析命令。
关键字:
装封;成帧;以太网;计算机通信
前言1
一、基本原理2
1、以太网工作原理2
2、以太网帧结构3
二、需求分析6
三、系统分析7
1、主流程7
2、封装帧8
3、解析帧14
四、分析结果22
五、心得体会23
六、参考文献24
前言
计算机网络是计算机技术与通信技术相互渗透、密切结合而形成的一门交叉学科。
计算机网络的应用可以大大缩短人与人交往的时间和空间的距离,更进一步扩大了人类社会群体之间相互与协作范围,因此人们一定会很快接受在计算机网络环境中的工作方式,同时计算机网络也会对社会的进步产生不可估量的作用。
计算机网络正在改变人们的工作方式和生活方式,网络技术的发展已成为影响一个国家与地区政治、经济、科学与文化发展的重要因素之一。
以太网是当今现有局域网采用的最通用的通信协议标准。
该标准定义了在局域网(LAN)中采用的电缆类型和信号处理方法。
以太网在互联设备之间以10-100Mbps的速率传送信息包,双绞线电缆10BaseT以太网由于其低成本、高可靠性以及10Mbps的速率而成为应用最为广泛的以太网技术。
许多制造商提供的产品都能采用通用的软件协议进行通信,开放性最好。
目前LAN接入方式就是俗称的“以太网”,带宽也达不到10-100Mbps,不过是2-4Mbps,比ADSL接入稍好一点。
一、基本原理
1、以太网工作原理
以太网采用共享信道的方法,即多台主机共用一个信道进行数据传输。
为了解决多个计算机的信道征用问题,以太网采用IEEE802.3标准规定的CSMA/CD(载波监听多路访问/冲突检测)协议,它是控制多个用户共用一条信道的协议,CSMA/CD的工作原理如下:
(1)载波监听(先听后发)
使用CSMA/CD协议时,总线上各个节点都在监听总线,即检测总线上是否有别的节点发送数据。
如果发现总线是空闲的,既没有检测到有信号正在传送,即可立即发送数据;如果监听到总线忙,即检测到总线上有数据正在传送,这时节点要持续等待直到监听到总线空闲时才能将数据发送出去,或等待一个随机时间,再从新监听总线,一直到总线空闲再发送数据。
载波监听也称作先听后发。
(2)冲突检测
当两个或两个以上的节点同时监听到总线空闲,开始发送数据时,就会发生碰撞冲突;传输延迟可能会使第一个节点发送的数据还没有到达目标节点时,另一个要发送的数据的节点就已经监听到总线空闲,并开始发送数据,这也会带至冲突的产生。
当两个帧发生冲突时,两个传输的帧就会被破坏,被损坏帧继续传输毫无意义,而且信道无法被其他站点使用,对于有限的信道来讲,这是很大的浪费。
如果每个发送节点边发送边监听,并在监听到冲突之后立即停止发送,就可以提高信道的利用率,当节点检测到纵向上发生冲突时,就立即取消传输数据,随后发送一个短的干扰信号,一个较强冲突信号,告诉网络上的所有的节点,总线已经发生了冲突。
在阻塞信号发生后,等待一个随机事件,然后再将要发送的数据发送一次。
如果还有冲突,则重复监听、等待和重传操作。
CSMA/CD采用用户访问总线时间不确定的随机竞争方式,有结构简单、轻负载时时延小等特点,但当网络通信负载增大时,由于冲突增多,网络吞吐率下降、传输延时增长,网络性能会明显下降。
从以上可看出以太网的工作方式就像没有支持人的座谈会中,所有的参会者都通过一个共同的介质来互相交谈。
每个参加会议的人在讲话前,都礼貌的等到别人把话讲完。
如果两个客人同时开始讲话,那么他们都停下来,分别随机等待一段时间再开始讲话,这是如果两个客人等待的时间不同,冲突就不会出现,如果讲话冲过了一次以上,将采用退避指数加强等待的时间。
2、以太网帧结构
帧格式
EthernetII帧格式:
----------------------------------------------------------------------------------------------
|前序 |目的地址 |源地址 |类型 |数据 |FCS |
----------------------------------------------------------------------------------------------|8byte | 6byte |6byte |2byte |46~1500byte |4byte|
IEEE802.3一般帧格式
--------------------------------------------------------------------------------------------------------------
|前序 |帧起始定界符|目的地址 |源地址|长度 |数据 |FCS |
------------------------------------------------------------------------------------------------------------
|7byte | 1byte |2/6byte |2/6byte|2byte|46~1500byte|4byte|
EthernetII和IEEE802.3的帧格式比较类似,主要的不同点在于前者定义的2字节的类型,而后者定义的是2字节的长度;所幸的是,后者定义的有效长度值与前者定义的有效类型值无一相同,这样就容易区分两种帧格式了。
1)前序字段
前序字段由8个(EthernetII)或7个(IEEE802.3)字节的交替出现的1和0组成,设置该字段的目的是指示帧的开始并便于网络中的所有接收器均能与到达帧同步,另外,该字段本身(在EthernetII中)或与帧起始定界符一起(在IEEE802.3中)能保证各帧之间用于错误检测和恢复操作的时间间隔不小于9.6毫秒。
2)帧起始定界符字段
该字段仅在IEEE802.3标准中有效,它可以被看作前序字段的延续。
实际上,该字段的组成方式继续使用前序字段中的格式,这个一个字节的字段的前6个比特位置由交替出现的1和0构成。
该字段的最后两个比特位置是11,这两位中断了同步模式并提醒接收后面跟随的是帧数据。
当控制器将接收帧送入其缓冲器时,前序字段和帧起始定界符字段均被去除。
类似地当控制器发送帧时,它将这两个字段(如果传输的是IEEE802.3帧)或一个前序字段(如果传输的是真正的以太网帧)作为前缀加入帧中。
3)目的地址字段
目的地址字段确定帧的接收者。
两个字节的源地址和目的地址可用于IEEE802.3网络,而6个字节的源地址和目的地址字段既可用于EthernetII网络又可用于IEEE802.3网络。
用户可以选择两字节或六字节的目的地址字段,但对IEEE802.3设备来说,局域网中的所有工作站必须使用同样的地址结构。
目前,几乎所有的802.3网络使用6字节寻址,帧结构中包含两字节字段选项主要是用于使用16比特地址字段的早期的局域网。
4)源地址字段
源地址字段标识发送帧的工作站。
和目前地址字段类似,源地址字段的长度可以是两个或六个字节。
只有IEEE802.3标准支持两字节源地址并要求使用的目的地址。
EthernetII和IEEE802.3标准均支持六个字节的源地址字段。
当使用六个字节的源地址字段时,前三个字节表示由IEEE分配给厂商的地址,将烧录在每一块网络接口卡的ROM中。
而制造商通常为其每一网络接口卡分配后字节。
5)类型字段
两字节的类型字段仅用于EthernetII帧。
该字段用于标识数据字段中包含的高层协议,也就是说,该字段告诉接收设备如何解释数据字段。
在以太网中,多种协议可以在局域网中同时共存,例如:
类型字段取值为十六进制0800的帧将被识别为IP协议帧,而类型字段取值为十六进制8137的帧将被识别为IPX和SPX传输协议帧。
因此,在EthernetII的类型字段中设置相应的十六进制值提供了在局域网中支持多协议传输的机制。
6)长度字段
用于IEEE802.3的两字节长度字段定义了数据字段包含的字节数。
不论是在EthernetII还是IEEE 802.3标准中,从前序到FCS字段的帧长度最小必须是64字节。
最小帧长度保证有足够的传输时间用于以太网网络接口卡精确地检测冲突。
基于最小帧长为64字节和使用六字节地址字段的要求,意味着每个数据字段的最小长度为46字节。
7)数据字段
如前所述,数据字段的最小长度必须为46字节以保证帧长至少为64字节,这意味着传输一字节信息也必须使用46字节的数据字段:
如果填入该该字段的信息少于46字节,该字段的其余部分也必须进行填充。
数据字段的最大长度为1500字节。
8)校验序列字段
既可用于EthernetII又可用于IEE802.3标准的帧校验序列字段提供了一种错误检测机制,每一个发送器均计算一个包括了地址字段、类型/长度字段和数据字段的循环冗余校验(CRC)码。
发送器于是将计算出的CRC填入四字节的FCS字段。
二、需求分析
依据以太网数据包格式,将前导码,目的地址,源地址与数据字段进行填充,对填充的数据字段的长度进行判断校验,若数据过长则封装成不同的帧进行发送并解析。
编写出程序封装数据包与解析数据包,并将解析后各包的头部与数据字段写入输入文件。
数据字段的值从封装的文件中获取。
三、系统分析
运行环境
平台:
WindowsXP
环境:
VC6.0
运行方式
a.点桌面的“开始”菜单->“运行”->键入“cmd”->进入控制台界面;
b.进入可执行程序所在文件夹并显示;
运行界面
1、主流程
●帮助命令“EthernetFrame/h”
●解析命令“EthernetFrame/u数据文件名”
●封装命令“EthernetFrame/e数据文件名”
2、封装帧
执行“EthernetFrame-einput”命令,在相应位置输入两次相同的信息,回车并结束输入,以实现以太网帧的封装。
在进行封装命令之前,首先要将帧结构中的前导码,帧前定界符,目的地址,源地址等四项内容填充,输入数据字段,并对数据进行校验,若数据字段过长则需将其封装成不同的帧进行发送,第一个帧被发送之后再发送第二个帧。
若少于46B的数据则要在后面填充“0”,发送封装帧后对总线的空闲状态要进行判断,只有在总线空闲时才可将其发送写入文件,接收并解析。
封装命令流程图
//Encap.cpp封装帧类的实现代码
#include
#include
#include
#include"Encap.h"
#include"CRC8.h"
usingnamespacestd;
/************************************************************************/
/*功能:
完成前导码到源地址的四项封装
/*输入参数:
fstream对象
/************************************************************************/
voidEncap:
:
HeaderEncap(fstream&file)
{
file.seekg(0,ios:
:
end);//将读指针移到文件末尾
for(inti=0;i<7;i++)//写入B的前导码和B的帧前定界符
file.put((char)0xaa);
file.put((char)0xab);
file.write(destination,6);//写入目的地址
file.write(source,6);//写入源地址
}
/************************************************************************/
/*功能:
处理数据字段
/*输入参数:
file:
fstream对象;inputstr:
等待封装的字符串
/************************************************************************/
intEncap:
:
DataDeal(fstream&file,stringinputStr)
{
intpackTotal=0;
intlength=inputStr.length();
if(length<=MINLENGTH)//如果输入文件长度不足46B,则用'0'补足
{
if(length { for(intj=0;j inputStr+='0'; cout<<"数据字段小于46,将封装成一个帧"< } else { cout<<"数据字段等于46,将封装成一个帧"< } packTotal=1; Encapsulate(file,inputStr,length);//将字符串内容写入到输出文件中 cout<<"第1个帧封装完毕! "< } else { intpackNum=1; if(length>MAXLENGTH)//如果输入文件长度大于最大值 { packNum=length/MAXLENGTH; if(length%MAXLENGTH)//计算封帧个数 { packNum++; } packTotal=packNum; cout<<"数据字段大于1500B,将封装成"< stringdivideStr;//本次拆分好的数据 stringleftStr=inputStr;//剩余未封装的数据 packNum=1; while(length>MAXLENGTH) { divideStr=leftStr.substr(0,MAXLENGTH); cout< leftStr=leftStr.substr(MAXLENGTH,length); length=leftStr.length(); Encapsulate(file,divideStr,MAXLENGTH); cout<<"第"< "< packNum++; } if(length { for(intj=0;j leftStr+='0'; } Encapsulate(file,leftStr,length);//将剩余字符串封装,length为字符串的真实长度,不是补足'0'后的长度 cout< cout<<"第"< "< packNum++; } else//如果输入文件长度小于等于最大值 { if(MAXLENGTH==length) { cout<<"数据字段等于1500B,将封装成1个帧"< } else { cout<<"数据字段介于46B和1500B之间,将封装成1个帧"< } packTotal=1; Encapsulate(file,inputStr,length);//将字符串封装 cout<<"第"< "< packNum++; } } returnpackTotal; } /************************************************************************/ /*功能: 完成剩余封装 /*输入参数: file: fstream对象;inputstr: 等待封装的字符串; /*length数据内容长度 /************************************************************************/ voidEncap: : Encapsulate(fstream&file,stringinputStr,intlength) { HeaderEncap(file);//封装头 constchar*inputChar=inputStr.data(); charinputLength[2]; inputLength[0]=length>>8; inputLength[1]=length&0xFF; file.put(inputLength[0]);//将字符串长度值前八位放入inputLength[0] file.put(inputLength[1]);//后八位放入inputLength[1] file.write(inputChar,inputStr.length());//inputChar可能被填充,因此它的长度不是原来的数据长度length unsignedcharCRC8=char(0x00);//CRC8初始化校验码 inti=0; for(i=0;i<6;i++)//校验目的地址、源地址 checkCRC(CRC8,destination[i]); for(i=0;i<6;i++) checkCRC(CRC8,source[i]); checkCRC(CRC8,inputLength[0]);//校验长度 checkCRC(CRC8,inputLength[1]); for(i=0;i checkCRC(CRC8,inputChar[i]); checkCRC(CRC8,0x00);//在校验对象后加0x00,校验完毕 file.put(CRC8);//将CRC8校验值封装到帧中 3、解析帧 执行“EthernetFrame-uinput”命令,以实现以太网帧的解析。 在解析命令中首先要读取input文件,从文件中找到帧,计算输入文件的长度与帧的个数,定位前导码,帧前定界符,目的地址,源地址等,输出帧序号,对其进行CRC校验,填充字符,输出前导码,帧前定界符,目的地址,源地址和数据字段并对数据字段进行校验,若校验后数据字段过于小则填充“0”,校验后输出状态,如图所示为两次解析的解析帧。 解析帧 解析帧1 解析命令流程图 //Unpack.cpp解析帧源文件代码 #include #include #include #include"Unpack.h"//解析帧类的定义 #include"CRC8.h"//定义了CRC8校验函数的头文件 usingnamespacestd; /************************************************************************/ /*功能: 在input中找到一个帧 /*输入参数: file,被读取的input文件 /************************************************************************/ voidUnpack: : FindFrame(fstream&file) { intnFileEnd=0;//输入文件的长度 file.seekg(0,ios: : end);//计算输入文件的长度 nFileEnd=file.tellg(); file.seekg(0,ios: : beg); intframeNum=1;//计算帧的个数,初值置为1 while(file.tellg() { for(intj=0;j<7;j++)//定位前导码,找到连续7个0xAA { if(file.tellg()>=nFileEnd) break; if(file.get()! =0xAA) j=-1; } if(file.tellg()>=nFileEnd) break; if(file.get()==0xAB)//定位帧前界定符 { inttemp=file.tellg(); if(temp+14>nFileEnd)//判断是否为一个完整的帧头 { break; } else//输出帧的序号 { cout< UnpackFrame(file); frameNum++; } } } if(0==frameNum) cout<<"没有找到合法的帧"<
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 兰州 理工大学 以太网 封装 设计 解析
![提示](https://static.bdocx.com/images/bang_tan.gif)