原创文章,未经许可请勿转载
IEEE 802.3以太网帧封装
- 设计内容
编写程序实现IEEE 802.3以太网帧封装。
二) 设计要求
1)基本要求:
A)要求画出界面,以太网帧的数据部分、源MAC地址和目的MAC地址均从界面输入;
B)计算后的校验和字段和封装后的结果可以从界面上输出;
C) 生成多项式G(X)=X8+X2+X+1;
D)使用的操作系统、语言和编译环境不限,但必须在报告中注明。
2)扩展要求:
A) 能够实现CRC计算过程的可视化;
B) 能够从界面上控制程序的运行。
3)相关理论知识
按802.3标准的帧结构如下表所示(802.3标准的Ethernet帧结构由7部分组成)
802.3标准的帧结构
前导码 | 帧前定界符 | 目的地址 | 源地址 | 长度字段 | 数据字段 | 校验字段 |
7B | 1B | (6B) | (6B) | (2B) | (长度可变) | (4B) |
其中,帧数据字段的最小长度为46B。如果帧的LLC数据少于46B,则应将数据字段填充至46B。填充字符是任意的,不计入长度字段值中。
在校验字段中,使用的是CRC校验。校验的范围包括目的地址字段、源地址字段、长度字段、LLC数据字段。
如题,这是一个经典的计算机网络课程设计题目,当时碰到这个题目的时候一度想做另一个题目,因为C系语言我基本上很少作为生产语言使用,java和Android使用的比较多,参考了CSDN上很多大佬的文章,还是感觉java的实现有点困难,C语言的又不会,算了,还是自己先写一个CRC校验的算法吧。
因为java中的好像对位运算不大好用,于是乎想着还是换一个方法替代吧--list
没错就是list,用它来存储、操作这些大量的二进制数也还是比较方便的(其实也可以用栈,只是觉得java栈这个数据结构比较麻烦,索性就直接上ArrayList了)
话不多说,上算法:
CRC校验的FCS算法
//CRC校验的FCS算法
public static ArrayList<Integer> getCRC(ArrayList<Integer> arrayList){
int[] cc = new int[]{1,0,0,0,0,0,1,1,1};//生成多项式
//末尾补0
for (int i = 0; i < 8; i++) {
arrayList.add(0);
}
int tag = 0;
ArrayList<Integer> resultList = new ArrayList<>(); //结果list
ArrayList<Integer> tempList = new ArrayList<>(); //余数缓存list
//循环开始
while (tag < arrayList.size() - 8){
ArrayList<Integer> arrayList1 = new ArrayList<>(); //本次运算取出的前9位
//若有余数,将余数先加入待计算串
for (int i = 0; i < tempList.size(); i++) {
arrayList1.add(tempList.get(i));
}
tempList.clear();
//补齐9位
for (int i = tag + arrayList1.size(); i < tag + cc.length; i++) {
arrayList1.add(arrayList.get(i));
}
//按位异或
for (int i = 0; i < cc.length;i++){
int res = arrayList1.get(i)^cc[i];
if (res == 0 && tempList.size() == 0)//首位0不计入余数
tag ++;
else tempList.add(res);
}
resultList = tempList;
}
//循环结束后,如果余数不足8位,则要在前面补0
if (resultList.size()<8){
ArrayList<Integer> temp = new ArrayList<>();
for (int i = 0; i < resultList.size(); i++) {
temp.add(resultList.get(i));
}
resultList.clear();
for (int i = 0; i < 8 - temp.size(); i++) {
resultList.add(0);
}
for (int i = 0; i < temp.size(); i++) {
resultList.add(temp.get(i));
}
}
return resultList;//最终的FCS校验码
}
上述算法便是我的CRC校验算法,入参为处理后的二进制串,ArrayList的每一位存储的都是一个二进制数,返回值同。
算法描述就到这里,如果还是有懒得动手的同学
到底了--