IP首部校验和计算与程序设计

一,感受与实验基本要求

这是我《计算机网络》这门课程的第二个实验,说实话这个实验吧,我觉得我完成的不是特别的好,好些地方都是取巧,并不是真正意义上的完成这个实验。但是我觉得还是把这个实验的前后写下来,毕竟是见证自己的一个成长。接下来我会先介绍一下实验要求与实验内容。

1.1 实验目的

1.掌握IP协议包结构;
2.学会IP协议包首部数据校验

1.2 实验要求

针对 IP 协议包结构,2 人一组,共同设计良好的人机界面,并实现首部校验和的计算程序。功能包括:
(1)在界面上,用户能够输入或编辑 IP 协议包各字段数据,例如,“协议”字段应该是下拉选择 方式;
(2)程序能够自动检查 IP 地址的合法性,且主机可用;
(3)能够自动计算首部校验和的值,并显示计算结果;
(4)必须验证程序的正确性:基于 Wireshark 工具所抓取的真实 IP 包首部数据,能够成功检验首 部校验和字段的计算程序。

二,实验内容

2.1 IP首部的基本校验方法

1,把IP数据包的校验和字段置为0;   
2,把首部看成以16位为单位的数字组成,依次进行二进制求和(注意:求和时应将最高位的进位保存,所以加法应采用32位加法);   
3,将上述加法过程中产生的进位(最高位的进位)加到低16位(采用32位加法时,即为将高16位与低16位相加,之后还要把该次加法最高位产生的进位加到低16位)   
4,将上述的和取反,即得到校验和。

2.2流程图

如图是流程图,可以先看看

2.3编程思路

2.3.1得到数据并进行标准化

首先,程序需要从交互界面获取十进制表示的IP头除了校验和的各部分数据。将这些数据转换成16进制形式的字符串,进行标准化,若不进行标准化,则容易在不同信息合并中因为结束出现问题。

String type1 = Edition.getSelectedItem();//获取所选内容
			String HeadLength1 = HeadLength.getText();//获取文本框内的内容
			String SeverType1 = SeverType.getSelectedItem();//下拉框的
			SeverType1 = flags_change(SeverType1);
			Sum[0] = Integer.parseInt(Connecting(type1,HeadLength1,SeverType1),16);//将版本,首部长度与服务结合,形成sum1。

如上,采集下拉框Edition(版本)(使用getSelectedItem()函数)、SeverType(服务类型)与文本框HeadLength(头部长度)(使用getText()函数)的填入字符串,然后通过Connecting()函数将字符串拼接起来,并通过parseInt()内置函数将其转换成16进制存储在sum[]数组中。

  采集
String S_IP1 = Length(encodeHEX(Integer.parseInt(S_IP_add1.getText())));
 标准化函数
public static String Length(String a) {
   
   	String b = null;
   	if(a.length()==1) b = "0" + a;
   	else if(a.length() == 2) b = a;
   	return b;
   }

是采集IP地址的第一个框的内容,而Length()的作用是标准化,将其表标准化为“xx”的形式,方便后面的拼接操作。

2.3.2 信息合并后,把字符串转换成十进制,并存储在数组中。

String AllLength2 = encodeHEX(Integer.parseInt(AllLength1));

将两个IP的范围的16进制形式通过Connecting()函数连接,通过parseInt(String,16)转化成10进制的int型,并存储在数组Sum[]中。
parseInt(String,16)的作用是把以字符串形式存储的16进制转换成10进制的整形。

public String Connecting(String a,String b,String c) {
   //将首部连接
		String d;
		if(c != null) {
   
			d = a+b+c;
		}else {
   
			d = a+b;
		}
		return d;
	}

看这个函数,可以决定是连接多少个首部,并存储在字符串中。

2.3.3 进行求和运算。用循环方式对数组内的10进制进行求和,并转换成字符串形式的16进制。

String SUM = count(Sum);

这是对Sum数组进行求和运算,Sum是一个数组,里面存着首部除了校验和之外的全部信息的十进制形式。

//先用10进制首部校验求和,然后转化成16进制
	public static String count(int[]  a) {
   
		int sum = 0;
		String end;
		for(int i = 0;i < 9;i++) {
   
			sum += a[i];
		}
		end = encodeHEX(sum);
		return end;
	}

为count()函数内部图,利用for循环将数组内部的10进制数字求和。这里返回的是和的16进制形式。

2.3.4 判断是否产生溢出,若产生溢出,依次将最高位的数字加在低位上,直到满足4位的16进制。

if(SUM.length()>4) {
   //若字长大于4位,则进行进位,将最高位加到最低位
				String s = SUM.substring(SUM.length()-4);
				String a = SUM.substring(0,1);
				int i = Integer.parseInt(s,16);
				int j = Integer.parseInt(a,16);
				SUM = encodeHEX(i+j);
			}

若字长大于4位,则进行切片操取出最高位和后四位,然后换成10进制后相加并换成16进制。

2.3.5 对进位后的和用ffff减去,所得的差即取反。

下面展示一些 内联代码片

//对16进制取反
	public String qufan(String a) {
   
		String m;
		int i,j = 0xffff;
		i = Integer.parseInt(a,16);
		m = encodeHEX(j-i);
		return m;
	}

如图,是进行取反的函数,将字符串a转换成10进制的整数后,用0xffff的10进制整数减去,再转换成16进制,即可得到去饭后的结果。此时整个运行结果结束。

三,程序运行界面与结果

3.1运行初始界面

程序的初始界面
在这里插入图片描述
如图,因为一个IP地址不合法(>255),检测出后进行提示,提示重新输入。
在这里插入图片描述
如上图,因为IP地址不合法(输入中有字母),检测出后进行提示,提示重新输入。
接下来我会简单介绍下判断是否合法是如何实现的。

//判断输入的IP是否全为10进制
	public boolean judge_ip(String a) {
   
		boolean b = null != null;
		for(int i=0 ; i<a.length() ; i++){
   
		if(Character.isLetter(a.charAt(i))) b = true;//用char包装类中的判断字母的方法判断每一个字符
		else b = false;
		}
		return b;
	}
	
	//判断IP是否合法
	public boolean Judge(String a) {
   
		int b = Integer.parseInt(a);
		if(b>=0&&b<=255) return true;
		else return false;
	}

如上,是进行检验的两个函数,第一个函数judge_ip()作用是检验IP地址是否均为数字10进制,若检测到字符则返回true;而第二个函数比较简单,是接受字符串的数字,换成整形后判断范围,若在范围内则说明IP正确,返回true,反正不正确。两者均返回布尔值,通过布尔值判断。

boolean judge1 = judge_ip(S_IP_add1.getText())||judge_ip(S_IP_add2.getText())||judge_ip(S_IP_add3.getText())||judge_ip(S_IP_add4.getText()||judge_ip(T_IP_add1.getText())||judge_ip(T_IP_add2.getText())||judge_ip(T_IP_add3.getText())||judge_ip(T_IP_add4.getText());
			if(judge1 == true) JOptionPane.showMessageDialog(null, "地址输入不合法!请重新输入");

如上,是进行是否均为10进制的判断。通过“或运算”,检查是否用10进制输入。因为judge_ip()函数是有字符就返回true,因此只需有一个true,则抛出提示,提示输入错误。

boolean judge = Judge(S_IP_add1.getText())&&Judge(S_IP_add2.getText())&&Judge(S_IP_add3.getText())
  • 12
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值