资源描述
学 号:
课 程 设 计
题 目
帧封装
学 院
计算机科学与技术学院
专 业
软件工程专业
班 级
软件0902班
姓 名
指引教师
年
6
月
20
日
课程设计任务书
学生姓名: 专业班级: 软件0902班
指引教师: 工作单位: 计算机学院
题目一:帧封装
初始条件:
(1)学习有关知识
(2)C/C++/VC/VB/JAVA语言
(3)PC机一台
规定完毕重要任务:(涉及课程设计工作量及其技术规定,以及阐明书撰写等详细规定)
编写程序,依照给出原始数据,组装一种IEEE802.3格式帧(题目默认输入文献为二进制原始数据(文献名为input1和input2))。
1)规定程序为命令行程序。例如,可执行文献名为framer.exe,则命令行形式如下:
framer inputfile outputfile
其中,inputfile为原始数据文献,outputfile为输出成果。使用操作系统、语言、编程环境不限,但在报告中必要注明。
2)输出:相应input1和input2成果分别为output1和output2。
时间安排:
第一、二天:查阅资料,学习算法
第三、四天:编程调试
第五天:书写报告
指引教师签名: 年 月 日
系主任(或责任教师)签名: 年 月 日
目录
1. 引言 4
2. 以太网帧格式发展 4
3. IEEE802.3帧构造 5
4. 错检测 6
5. 实现环节 7
5.1 前导符 7
5.2 目地址及源地址 7
5.3 长度及数据字段 8
5.4 帧检查序列 8
6. 源代码 10
7. 运营成果示例 17
8. 心得体会 18
9. 参照文献 19
帧封装
1. 引言
以太网这个术语普通是指由DEC、Intel和Xerox公司在1982年联合发布一种原则,它是当今TCP/IP采用重要局域网技术,它采用一种称作CSMA/CD媒体接入办法。在TCP/IP世界中,以太网IP数据报文封装在RFC 894中定义。
以太网采用广播机制,所有与网络连接工作站都可以看到网络上传递数据。通过查看包括在帧中目的地址,拟定与否进行接受或放弃。如果证明数据的确是发给自己,工作站将会接受数据并传递给高层合同进行解决。
以太网采用CSMA/CD(Carrier Sense Multiple Access/Collision Detection)媒体访问机制,任何工作站都可以在任何时间访问网络。在以太网中,所有节点共享传播介质。如何保证传播介质有序、高效地为许多节点提供传播服务,就是以太网介质访问控制合同要解决问题。
帧是在数据链路层数据进行传播与互换基本单位。构造帧对于理解网络合同概念、合同执行过程以及网络问题解决普通办法具备重要意义。本次课程设计目是应用数据链路层与介质访问控制层知识,依照数据链路层基本原理,通过构造一种详细Ethernet帧,从而进一步理解网络合同基本概念与网络问题解决普通办法。
2. 以太网帧格式发展
1980,DEC、Intel、Xerox制定了Ethernet I原则;
1982,DEC、Intel、Xerox又制定了Ehternet II原则;
1982,IEEE开始研究Ethernet国际原则802.3;
1983,迫不及待Novell基于IEEE802.3原始版开发了专用Ethernet帧格式;
1985,IEEE推出IEEE 802.3规范,日后为解决EthernetII与802.3帧格式兼容问题,推出折衷Ethernet SNAP格式。
3. IEEE802.3帧构造
数据在网络上是以很小称为帧(Frame)单位传播,帧由几某些构成,不同某些执行不同功能。帧通过特定称为网络驱动程序软件进行成型,然后通过网卡发送到网线上,通过网线到达它们目机器,在目机器一端执行相反过程。接受端机器以太网卡捕获到这些帧,并告诉操作系统帧已到达,然后对其进行存储。
“帧”数据大体由两某些构成:帧头和帧数据。帧头涉及接受方主机物理地址定位以及其他网络信息。帧数据区具有一种数据体。为保证计算机可以解释数据帧中数据,这两台计算机使用一种公用通讯合同。互联网使用通讯合同简称IP,即互联网合同。IP数据体由两某些构成:数据体头部和数据体数据区。数据体头部涉及IP源地址和IP目的地址,以及其他信息。数据体数据区涉及顾客数据合同(UDP),传播控制合同(TCP),尚有数据包其她信息。这些数据包都具有附加进程信息以及实际数据。
8
6
6
2
46 – 1500
4
前导符
目地址
源地址
长度
数据
FCS
图3.1 IEEE802.3帧构造
惯用以太网MAC帧格式用两种原则,一种是DIX Ethernet V2原则(即以太网V2原则),另一种是IEEE802.3原则。这里只简介符合IEEE802.3原则帧,其格式如图3.1所示。
它构成比较简朴,由6个字段构成。接下来对这6个某些详细简介一下。
(1)前导符:由7字节前同步码和1字节帧起始定界符构成。
前同步码:这个字段有7个字节(56位)交替浮现1和0,它作用就是提示接受系统有帧到来,以及使到来帧与计时器进行同步。前同步码其实是在物理层添加上去,并不是(正式)帧一某些。前同步码目的是容许物理层在接受到实际帧起始符之前检测载波,并且与接受到帧时序达到稳定同步。
帧起始定界符:这个字段用1字节(10101011)作为帧开始信号,表达一帧开始。最后两位是11,表达下面字段是目地址。
(2)目地址(DA) 48位,表达帧准备发往目站地址,共6个字节,可以是单址(代表单个站)、多址(代表一组站)或全地址(代表局域网上所有站)。
当目地址浮现多址时,表达该帧被一组站同步接受,称为“组播”(Multicast)。目地址浮现全地址时,表达该帧被局域网上所有站同步接受,称为“广播”(Broadcast),普通以DA最高位来判断地址类型,若第一字节最低位为“0”则表达单址,第一字节最低位为“1”则表达组播。
(3)源地址(SA)48位,表白该帧数据是哪个网卡发,即发送端网卡地址。
(4)该字段是“长度/类型”。当这个字段值不不大于0X0600时(相称于十进制1536),就表达“类型”。这样帧和以太网V2 MAC帧完全同样。只有当这个字段值不大于0X0600时才表达“长度”,即MAC帧数据某些长度。
(5)数据字段最小长度必要为46字节以保证帧长至少为64字节,这意味着传播一字节信息也必要使用46字节数据字段:如果填入该字段信息少于46字节,该字段别的某些也必要进行填充。数据字段默认最大长度为1500字节。
(6)帧检查序列(FCS)是32位冗余检查码(CRC),检查除前导、SFD和FCS以外内容。当发送站发出帧时,一边发送,一边逐位进行CRC检查。最后形成一种32位CRC检查和填在帧尾FCS位置中一起在媒体上传播。接受站接受后,从DA开始同样边接受边逐位进行CRC检查。最后接受站形成检查和若与帧检查和相似,则表达媒体上传播帧未被破坏。反之,接受站以为帧被破坏,则会通过一定机制规定发送站重发该帧。
4. 错检测
在校验字段中,使用是CRC校验。校验范畴涉及目地址字段、源地址字段、长度字段、LLC数据字段。
循环冗余编码(CRC)是一种重要线性分组码、编码和解码办法,具备简朴、检错和纠错能力强等特点,在通信领域广泛地用于实现差错控制。CRC校验码检错能力很强,不但能检查出离散错误,还能检查出突发错误。
运用CRC进行检错过程可简朴描述如下:在发送端依照要传送k位二进制码序列,以一定规则产生一种校验用r位监督码(CRC码),附在原始信息后边,构成一种新二进制码序列(共k+r位),然后发送出去。在接受端,依照信息码和CRC码之间所遵循规则进行检查,以拟定传送中与否出错。这个规则在差错控制理论中称为“生成多项式”。
循环冗余校验码特点:
(1)CRC校验码可检测出所有单个错误。
(2)CRC校验码可检测出所有奇数位错误。
(3)CRC校验码可检测出所有双位错误。
(4)CRC校验码可检测出所有不大于、等于校验位长度突发错误。
(5)CRC校验码可以 概率检测出长度为(K+1)位突发错误。
5. 实现环节
1
2
3
4
5
5.1 前导符
前导符涉及7字节前发送码和1字节帧起始定界符。由于这些都是固定写法,因而添加起来非常简朴。相应办法如下。
public static boolean appendPrefix() {
// 前导符中前7个字节是交替浮现1和0
for (int i = 0;i < 7;++i) {
tmp.add(0XAA);
}
// 前导符第8个字节是商定好0XAB
tmp.add(0XAB);
return true;
}
5.2 目地址及源地址
咱们懂得,目机器硬件地址是通过ARP合同得到,这需要发送ARP祈求包才干得到,为了简化程序设计,突出本次设计要点,因而将目地址固定写成“FF:FF:FF:FF:FF:FF”。类似地,获得本机地址也需要通过一系列函数调用,在程序中就直接写成已知硬件地址“74:E5:0B:7D:CE:3A”。相应办法如下。
public static boolean appendAddress() {
// 由于未显式规定目地址,因而程序中将目地址固定为FF:FF:FF:FF:FF:FF
for (int i = 0;i < 6;++i) {
tmp.add(0XFF);
}
// 本机地址为74:E5:0B:7D:CE:3A
tmp.add(0X74);
tmp.add(0XE5);
tmp.add(0X0B);
tmp.add(0X7D);
tmp.add(0XCE);
tmp.add(0X3A);
return true;
}
5.3 长度及数据字段
对于发送端来说,必要先获得数据长度,将长度字段添加到帧中之后才干再添加数据字段,这就限定了必要访问输入文献两次,第一次用于获得文献长度,第二次用于封装帧。固然在进行CRC计算时候有某些地方可以优化。
本程序文献是通过FileInputStream进行读入,通过FileOutputStream进行输出。
5.4 帧检查序列
计算FCS是本程序最困难某些。算法描述如下:
(1)输入需要检查序列M,以及发送方与接受方商定好除数P,并初始化余数R为0,若P有n位,则R有n – 1位;
(2)对序列M中每一位(记为b)进行环节(3)。结束后R即为FCS。
(3)将R左移1位,并将b添加到R最低位,判断R最高位,如果是0,则继续(3),如果是1,则将R和P进行按位与操作,成果保存到R中。
图5.4.1 CRC流程图
相应流程图如图5.4.1所示,其实现如下,其中curByte为一种字节,currentR为从开始到当前已经循环计算所得余数。
public static int nextR(int currentR,int curByte) {
int mask = 0X80;
int curBit = 0;
for (int i = 0;i < 8;++i,mask >>= 1) {
// 计算当前位,0或者1
curBit = (curByte & mask) == 0 ?0X0 :0X1;
// 一方面将余数左移1位,并把当前位添加到余数最低位
currentR <<= 1;
currentR += curBit;
// 判断余数最高位与否为0
// 若为1,则将除数和余数进行异或操作,将成果保存为余数
if ((currentR & MASK_HIGH) != 0) {
currentR = currentR ^ P;
}
}
return currentR;
}
6. 源代码
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.LinkedList;
import java.util.List;
public class framer {
public static void main(String[] args) throws IOException {
if (args.length < 2) {
System.out.println("参数错误!");
return;
}
FileInputStream fin = null;
FileOutputStream fout = null;
try {
fin = new FileInputStream(new File(args[0]));
fout = new FileOutputStream(args[1]);
} catch (IOException e) {
System.out.println("文献错误!");
return;
}
// 添加前导符
appendPrefix();
// 添加目地址和源地址
appendAddress();
// 添加数据,涉及数据长度、数据内容以及帧检查序列
appendData(fin,fout);
fin.close();
fout.close();
}
/**
* 添加8个字节前导符
*
* @return 添加成功时返回true,否则false
*/
public static boolean appendPrefix() {
// 前导符中前7个字节是交替浮现1和0
for (int i = 0;i < 7;++i) {
tmp.add(0XAA);
}
// 前导符第8个字节是商定好0XAB
tmp.add(0XAB);
return true;
}
/**
* 添加6个字节目地址,和添加6个字节源地址
*
* @return 添加成功时返回true,否则false
*/
public static boolean appendAddress() {
// 由于未显式规定目地址,因而程序中将目地址固定为FF:FF:FF:FF:FF:FF
for (int i = 0;i < 6;++i) {
tmp.add(0XFF);
}
// 本机地址为74:E5:0B:7D:CE:3A
tmp.add(0X74);
tmp.add(0XE5);
tmp.add(0X0B);
tmp.add(0X7D);
tmp.add(0XCE);
tmp.add(0X3A);
return true;
}
/**
* 添加2个字节数据长度,接着添加数据字段,最后添加帧检查序列FCS
*
* @param in
* 输入文献
* @param out
* 输出流
* @return 添加成功时返回true,否则false
*/
public static boolean appendData(InputStream in,OutputStream out) {
int[] data = new int[MAX_SIZE];
// 文献长度
int size = 0;
// 当前字节
int curByte = 0;
try {
while (size < MAX_SIZE && (curByte = in.read()) != -1) {
data[size++] = curByte;
}
} catch (IOException e1) {
e1.printStackTrace();
return false;
}
// 一方面添加2个字节数据长度
tmp.add(size >> 8);
tmp.add(size);
// 然后添加数据字段
for (int i = 0;data[i] != -1 && i < size;++i) {
tmp.add(data[i]);
}
// 若数据长度局限性,则补充填充字节
if (size < MIN_SIZE) {
for (int i = 0;i < MIN_SIZE - size;++i) {
tmp.add(FILL_BYTE);
}
}
// 计算FCS
// 初始化余数为0
int R = 0;
try {
for (int b :tmp) {
// 每次读入一种字节,将它添加到帧中,并且循环计算FCS
out.write(b);
R = nextR(R,b);
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
try {
// 最后添加4个字节帧检查序列
out.write(R >> 24);
out.write(R >> 16);
out.write(R >> 8);
out.write(R);
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
public static int nextR(int currentR,int curByte) {
int mask = 0X80;
int curBit = 0;
for (int i = 0;i < 8;++i,mask >>= 1) {
// 计算当前位,0或者1
curBit = (curByte & mask) == 0 ?0X0 :0X1;
// 一方面将余数左移1位,并把当前位添加到余数最低位
currentR <<= 1;
currentR += curBit;
// 判断余数最高位与否为0
// 若为1,则将除数和余数进行异或操作,将成果保存为余数
if ((currentR & MASK_HIGH) != 0) {
currentR = currentR ^ P;
}
}
return currentR;
}
// 数据字段最大长度
public static final int MAX_SIZE = 1500;
// 数据字段最小长度
public static final int MIN_SIZE = 46;
// 填充字节
public static final int FILL_BYTE = 0X00;
// 发送方与接受方商定好除数P
public static final int P = 0XACEF1357;
// 用于判断余数最高位与否为1掩码
public static final int MASK_HIGH = 0X8000;
private static List<Integer> tmp = new LinkedList<Integer>();
}
7. 运营成果示例
为了演示需要,一方面新建一种文本文献,内容为“ChenJiaHui”(不含引号),如图7.1所示。用文本文献一种好处是可以以便检测输出文献(即帧格式)与否对的。
图7.1 输入文献
接下来将源程序进行编译和运营。命令“javac”表达将源代码编译成类文献。命令“java”表达执行一种类文献,其后跟着“input1 input2”分别表达输入文献和输出文献,其中输入文献是所要包装数据,即上文提到文本文献,输出文献表达将帧封装好之后保存到哪个文献中,文献不存在时自动创立,存在时会覆盖。如图7.2所示。
图7.2 编译运营
由于实验只需要将数据封装成帧,并不规定检查,但如果不检查话,又不懂得与否封装对的,因而我此外写了一段程序,用以检查帧与否封装对的。在图7.3中可以看到,这个类名字为“check”,它接受一种参数,用以指明所要检查帧,这里是“input2”,即由framer程序产生帧文献。由于input2是一种二进制文献,因而无法通过普通编辑器将其打开以查看其中内容。
图7.3 检测输出文献
第一行有64位,前56位是前同步码,后8位是帧起始定界符。
第二行是目地址。由于没有显示指定目地址,因此程序中将目地址设为“FF:FF:FF:FF:FF:FF”。
第三行是源地址。源地址为本机MAC地址。
第四行是长度,表达原输入文献大小。由于输入文献input1只具有“ChenJiahui”10个字符,因而该文献大小确是10.
接下来十行是源文献中10个字节,为了避免输出过于冗余,因此只输出前10个字节,可以看到,每个字节均相应对的字符,例如“1000011”表达字符“C”。
最后四行是4个字节FCS。
以上输出中,有些字节局限性8位,是由于均忽视了前导0。
8. 心得体会
帧是数据链路层最重要概念。数据链路层属于计算机网络低层。咱们懂得,两个主机之间数据传播,总是在一段一段链路上传送,也就是说,在两个相邻结点之间(主机和路由器或两个路由器之间)传送数据是直接传送(点对点)。这时就需要专门链路层合同。在两个相邻结点之间传送数据时,数据链路层将网络层交下来IP数据报组装成帧(framing),在两个相邻结点间链路上“透明”地传送帧(frame)中数据。每一帧涉及数据和必要控制信息(犹如步信息、地址信息、差错控制等)。典型帧长是几百字节到一千多字节。
在接受数据时,控制信息使接受端可以懂得一种帧从哪个比特开始和到哪个比特结束。这样,数据链路层收到一种帧后,就可从中提取出数据某些,上交给网络层。
控制信息还使接受端可以检测到所收到帧中有无差错。如发既有差错,数据链路层就简朴地丢弃这个浮现差错帧,以免继续传送下去白白挥霍网络资源。
在本次课程设计中,刚开始两天我先是收集资料,查阅了诸多帧封装知识,对帧及其封装办法有了一定限度理解和掌握。从最开始对帧一种模糊印象到对帧构造完全掌握,有了很大收获,并且使帧封装得以实现。
同步,在近一周课程设计中,我动手能力得到了很大提高,并且将这学期所学网络知识和此前所学编程知识充分联系起来,对这门课结识又提高了一层。除此之外,在做课程设计时候也遇到了诸多问题,最后在同窗协助下对的解决了。从最开始遇到问题到最后对的解决问题,我懂得了对的出来问题办法,也懂得了自己局限性之处。本次课程设计也是一种结识自我好机会。
9. 参照文献
[1] 谢希仁. 计算机网络. 第5版. 北京. 电子工业出版社. .1.1
[2] 唐朔飞. 计算机构成原理. 第2版. 北京. 高等教诲出版社. .1.1
[3] (美)特南鲍姆,(美)韦瑟罗尔 著. 严伟,潘爱民 译. 计算机网络. 第5版. 北京. 清华大学出版社. .3.1
[4] (美)埃克尔 著. 陈昊鹏 译. Java编程思想. 第4版. 北京. 机械工业出版社. .6.1
本科生课程设计成绩评估表
班级:软件工程0902班 姓名: 学号:
序号
评分项目
满分
实得分
1
学习态度认真、遵守纪律
10
2
设计分析合理性
10
3
设计方案对的性、可行性、创造性
20
4
设计成果对的性
40
5
设计报告规范性
10
6
设计验收
10
总得分/级别
评语:
注:最后成绩以五级分制记。优(90-100分)、良(80-89分)、中(70-79分)、
及格(60-69分)、60分如下为不及格
指引教师签名:
201 年 月 日
展开阅读全文