导航:首页 > 计算方法 > udp校验和计算方法

udp校验和计算方法

发布时间:2022-01-19 07:18:57

❶ IP/UDP/TCP/ICMP数据报协议的校验和的区别和计算

首先,IP、ICMP、UDP和TCP报文头部都有校验和字段,大小都是16bit,算法也基本一样:
在发送数据时,为了计算数据包的校验和。应该按如下步骤:
(1)把校验和字段置为0;
(2)把需校验的数据看成以16位为单位的数字组成,依次进行二进制反码求和;(3)把得到的结果存入校验和字段中。在接收数据时,计算数据包的校验和相对简单,按如下步骤:
(1)把首部看成以16位为单位的数字组成,依次进行二进制反码求和,包括校验和字段;
(2)检查计算出的校验和的结果是否为0;
(3)如果等于0,说明被整除,校验是和正确。否则,校验和就是错误的,协议栈要抛弃这个数据包。

虽然上面四种报文的校验和算法一样,但在作用范围存在不同:IP校验和只校验20字节的IP报头;而ICMP校验和覆盖整个报文(ICMP报头+ICMP数据);UDP和TCP校验和不仅覆盖整个报文,而且还有12字节的IP伪首部,包括源IP地址(4字节)、目的IP地址(4字节)、协议(2字节,第一字节补0)和TCP/UDP包长(2字节)。另外UDP、TCP数据报的长度可以为奇数字节,所以在计算校验和时需要在最后增加填充字节0(注意,填充字节只是为了计算校验和,可以不被传送)。
这里还要提一点,UDP的校验和是可选的,当校验和字段为0时,表明该UDP报文未使用校验和,接收方就不需要校验和检查了!那如果UDP校验和的计算结果是0时怎么办呢?书上有这么一句话:“如果校验和的计算结果为0,则存入的值为全1(65535),这在二进制反码计算中是等效的。”

讲了这么多,那这个校验和到底是怎么算的呢?

1. 什么是二进制反码求和
对一个无符号的数,先求其反码,然后从低位到高位,按位相加,有溢出则向高位进1(跟一般的二进制加法规则一样),若最高位有进位,则向最低位进1。

首先这里的反码好像跟我们以前学的有符号数的反码不一样(即正数的反码是其本身,负数的反码是在其原码的基础上,符号位不变,其余各位取反),这里不分正负数,直接每个位都取反!

上面加粗的那句是跟我们一般的加法规则不太一样的地方:最高位有进位,则向最低位进1。确实有些疑惑,为什么要这样做呢?仔细分析一下(为了方便说明,以 4bit二进制反码求和举例),上面的这种操作,使得在发生加法进位溢出时,溢出的值并不是10000,而是1111。也即是当相加结果满1111时溢出,这样也可以说明为什么0000和1111都表示0了(你同样可以发现,任何数与这两个数做二进制反码求和运算结果都是原数,这恰好符合数0的加法意义)。

下面再举例两种二进制反码求和的运算:
原码加法运算 反码加法运算
3(0011)+ 5(0101)= 8(1000) 3(1100)+ 5(1010)= 8(0111)
8(1000)+ 9(1001)= 1(0001) 8(0111)+ 9(0110)= 2(1101)
从上面两个例子可以看出,当加法未发生溢出时,原码与反码加法运算结果一样;当有溢出时,结果就不一样了,原码是满10000溢出,而反码是满1111溢 出,所以相差正好是.
1。举例只是为了形象地观察二进制反码求和的运算规则,至于为什么要定义这样的规则以及该运算规则还存在其它什么特性,可能就需要涉及 代数理论的东西的了(呜呜~~数学理论没学好啊,只能从表面上分析分析)。

另外关于二进制反码求和运算需要说明的一点是,先取反后相加与先相加后取反,得到的结果是一样的!(事实上我们的编程算法里,几乎都是先相加后取反。)

2. 校验和算法的实现

讲了什么是二进制反码求和,那么校验和的算法实现就简单多了。废话少说,直接上代码:

[cpp] view plain
//计算校验和
USHORT checksum(USHORT *buffer,int size)
{
unsigned long cksum=0;
while(size>1)
{
cksum+=*buffer++;
size-=sizeof(USHORT);
}
if(size)
{
cksum+=*(UCHAR *)buffer;
}
//将32位数转换成16
while (cksum>>16)
cksum=(cksum>>16)+(cksum & 0xffff);
return (USHORT) (~cksum);
}
buffer是指向需校验数据缓存区的指针,size是需校验数据的总长度(字节为单位)

4~13行代码对数据按16bit累加求和,由于最高位的进位需要加在最低位上,所以cksum必须是32bit的unsigned long型,高16bit用于保存累加过程中的进位;另外代码10~13行是对size为奇数情况的处理!

14~16行代码的作用是将cksum高16bit的值加到低16bit上,即把累加中最高位的进位加到最低位上。这里使用了while循环,判断cksum高16bit是否非零,因为第16行代码执行的时候,仍可能向cksum的高16bit进位。
有些地方是通过下面两条代码实现的:
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
这里只进行了两次相加,即可保证相加后cksum的高16位为0,两种方式的效果一样。事实上,上面的循环也最多执行两次!

17行代码即对16bit数据累加的结果取反,得到二进制反码求和的结果,然后函数返回该值。

3. 为什么使用二进制反码求和呢?

好了,最后一个问题,为什么要使用二进制反码来计算校验和呢,而不是直接使用原码或者补码?
这个问题我想了很久,由于水平有限实在弄不明白,于是在网络上一阵狂搜,什么都没有(不知道是网络不给力,还是大家都不关注这个问题呢?)。果断换google,敲了3个关键词:why checksum tcp,嘿嘿 结果第二篇就是我想要的文章了!!!
先把链接给大家吧:http://www.netfor2.com/checksum.html
这篇文章主要介绍二进制反码求和(the 1's complement sum)与补码求和(the 2's complement sum)的区别,另外还说明了在TCP/IP校验和中使用反码求和的优点。

It may look awkword to use a 1's complement addition on 2's complement machines. This method however has its own benefits.
Probably the most important is that it is endian independent. Little Endian computers store hex numbers with the LSB last (Intel processors for example). Big Endian computers put the LSB first (IBM mainframes for example). When carry is added to the LSB to form the 1's complement sum (see the example) it doesn't matter if we add 03 + 01 or 01 + 03. The result is the same.
Other benefits include the easiness of checking the transmission and the checksum calculation plus a variety of ways to speed up the calculation by updating only IP fields that have changed.
上面是原文的一部分,说明在TCP/IP校验和中使用反码求和的一些优点:
a. 不依赖系统是大端还是小端。 即无论你是发送方计算或者接收方检查校验和时,都不需要调用htons 或者 ntohs,直接通过上面第2节的算法就可以得到正确的结果。这个问题你可以自己举个例子,用反码求和时,交换16位数的字节顺序,得到的结果相同,只是字节顺序相应地也交换了;而如果使用原码或者补码求和,得到的结果可能就不相同!
b. 计算和验证校验和比较简单,快速。说 实话,这个没怎么看明白,感觉在校验和计算方面,原码或者补码求和反而更简单一些(从C语言角度),在校验和验证上面,通过一样的算法判断结果是否为全 0,确实要方便一些,所以可能从综合考虑确实反码求和要简便一些。另外,IP报文在传输过程中,路由器经常只修改TTL字段(减1),此时路由器转发该报 文时可以直接增加它的校验和,而不需要对IP整个首部进行重新计算。当然,可能从汇编语言的角度看,反码求和还有很多高效的地方,这里就不在深入追究 了~~~

❷ 怎么计算UDP检验和(最好是有详细例子分析)

去查书吧
谢希仁《计算机网络>上有
你先看ip检验和那节,再看udp那节

❸ IP/UDP/TCP/ICMP数据报协议的校验和的区别和计算

1、把校验和字段置为0;

2、对IP头部中的每16bit进行二进制求和;

3、如果和的高16bit不为0,则将和的高16bit和低16bit反复相加,直到和的高16bit为0,从而获得一个16bit的值;

4、将该16bit的值取反,存入校验和字段。

❹ 用java实现UDP校验和计算

public static void main(String[] arg) {
String str = "hello";
System.out.println(toByte(str));
// 得到结果:byte[] sbytes = { 0X68, 0X65, 0X6c, 0X6c, 0X6f };
}

private static String toByte(String str) {
byte[] bytes = str.getBytes();
StringBuffer sb = new StringBuffer();
sb.append("byte[] sbytes = { ");
for (int i = 0; i < bytes.length; i++) {
sb.append(String.format("0X%s", Integer.toHexString(bytes[i])));
if (i < bytes.length - 1) {
sb.append(", ");
}
}
sb.append(" };").append("\r\n");
return sb.toString();
}

❺ UDP计算校验和为什么要用1的补码

UDP的校验和包括UDP首部和数据,方法是计算16位的二进制和,首先将校验
和字段(16位)置0,将每个16位的反码相加,若是奇数字节即最后未到16字节,
则以0补充,结果存在校验和字段中,因接收端包含了之前的校验和,若传输
中没有任何差错,则接收端计算的校验和该为全1,否则有错。

❻ UDP伪首部的作用和怎么计算UDP的检验和这个检验和是否涵盖伪首部内容还是只是UDP数据包的内容

首先,要时刻谨记一个“伪”字,既然是“伪”首部,也就是假的,不仅是“假”首部,而且“假”到连地址空间都没有。也就是说伪首部是不占地址空间的,在实际传输中不存在这样的字段。只是在使用的时候把它拿出来一下。
其次,设置了伪首部,为了计算检验和!书中原话“其目的是让UDP两次检查数据是否已经正确到达目的地”,具体是那两次呢?我们注意伪首部字段:32位源IP地址、32位目的IP地址、8位协议、16位UDP长度。由此可知,第一次,通过伪首部的IP地址检验,UDP可以确认该数据报是不是发送给本机IP地址的;第二,通过伪首部的协议字段检验,UDP可以确认IP有没有把不应该传给UDP而应该传给别的高层的数据报传给了UDP。从这一点上,伪首部的作用其实很大。

如何计算UDP/TCP检验和checksum

如何计算UDP/TCP检验和checksum 一、下面的图是一个UDP的检验和所需要用到的所有信息,包括三个部分: 1.UDP伪首部 2.UDP首部 3.UDP的数据部分(切记不要遗漏该部分,否则就~吐血了~) 首先解释下伪首部的概念,伪首部包含IP首部一些字段。其目的是让UDP两次检查数据是否已经正确到达目的地,只是单纯为了做校验用的。 还有一个概念十分重要,那就是16位UDP总长度,请注意该长度不是报文的总长度,而只是UDP(包括UDP头和数据部分)的总长度(之前就是因为这个概念没弄清楚,走了不少弯路,吐血~~)。 二、计算检验和(checksum)的过程很关键,主要分为以下几个步骤: 1.把伪首部添加到UDP上; 2.计算初始时是需要将检验和字段添零的; 3.把所有位划分为16位(2字节)的字 4.把所有16位的字相加,如果遇到进位,则将高于16字节的进位部分的值加到最低位上,举例,0xBB5E+0xFCED=0x1 B84B,则将1放到最低位,得到结果是0xB84C 5.将所有字相加得到的结果应该为一个16位的数,将该数取反则可以得到检验和checksum。 三、事实胜于雄辩,还是举个例子来分析一下吧,该例子计算的是一个TCP的检验和(和UDP的算法一致) TCP计算检验和的报文结构如下所示: 抓包工具抓了一个TCP 的syn报文做研究,呵呵,下面就是整个报文: 1.首先将检验和部分添零; 2.然后将TCP伪首部部分,TCP首部部分,数据部分都划分成16位的一个个16进制数; 3.将这些数逐个相加,记得溢出的部分加到最低位上,这是循环加法: 0xc0a8+ 0x0166+……+0x0402=0x9b49 4.最后将得到的结果取反,则可以得到检验和位0x64B6 按照上述步骤进行计算就可以得到检验和为0x64B6,大家也可以试试看 IP数据报只检验IP数据报的首部,但UDP检验的是把首部和数据部分一起都检验。

❽ 校验和怎么计算

检验和(checksum),在数据处理和数据通信领域中,用于校验目的地一组数据项的和。它通常是以十六进制为数制表示的形式。如果校验和的数值超过十六进制的FF,也就是255. 就要求其补码作为校验和。通常用来在通信中,尤其是远距离通信中保证数据的完整性和准确性。
这些数据项可以是数字或在计算检验的过程中看作数字的其它字符串。校验和(checksum)是指传输位数的累加,当传输结束时,接收者可以根据这个数值判断是否接到了所有的数据。如果数值匹配,那么说明传送已经完成。TCP和UDP传输层都提供了一个校验和与验证总数是否匹配的服务功能。[1]

它通常是以十六进制为数制表示的形式
发送方生成检验和

1.将发送的进行检验和运算的数据分成若干个16位的位串,每个位串看成一个二进制数,这里并不管字符串代表什么,是整数、浮点数还是位图都无所谓。

2.将IP、UDP或TCP的PDU首部中的检验和字段置为0,该字段也参与检验和运算。

3.对这些16位的二进制数进行1的补码和(one'scomplementsum)运算,累加的结果再取反码即生成了检验码。将检验码放入检验和字段中。

其中1的补码和运算,即带循环进位(end round carry)的加法,最高位有进位应循环进到最低位。反码即二进制各位取反,如0111的反码为1000。

接收方校验检验和

1.接收方将接收的数据(包括检验和字段)按发送方的同样的方法进行1的补码和运算,累加的结果再取反码。

2.校验,如果上步的结果为0,表示传输正确;否则,说明传输有差错。

❾ IP,UDP,TCP校验和有什么区别

UDP计算校验和的方法和计算IP数据报首部校验和的方法相似。 但不同的是:IP数据报的校验和只检验IP数据报的首部,但UDP的校验和是将首部和数据部分一起都检验。 在发送端,首先是将全零放入检验和字段。再将伪首部以及UDP用户数据报看成是由许多16bit的字串接起来。 若UDP用户数据报的数据部分不是偶数个字节,则要填入一个全零字节(即:最后一个基数字节应是16位数的高字节而低字节填0)。 然后按二进制反码计算出这些16bit字的和(两个数进行二进制反码求和的运算的规则是:从低位到高位逐列进行计算。 0和0相加是0,0和1相加是1,1和1相加是0但要产生一个进位1,加到下一列。若最高位相加后产生进位,则最后得到的结果要加1)。 将此和的二进制反码写入校验和字段后,发送此UDP用户数据报。 在接收端,将收到的UDP用户数据报连同伪首部(以及可能的填充全零字节)一起,按二进制反码求这些16bit字的和。 当无差错时其结果应全为1。否则就表明有差错出现, 接收端就应将此UDP用户数据报丢弃(也可以上交给应用层,但附上出现了差错的警告)。
TCP 的校验和计算方法同UDP一样,同样要加上一个伪头部,区别是伪头部的协议码是0x06,长度是整个TCP报文的长度(包含TCP头部)。

ICMP的校验和

ICMP校验和的计算方法一样,只不过只是对ICMP包整个进行校验和,没有伪头部,也不包括IP包头部。

❿ java UDP检验和计算

byte ->char 强制转换,,, 直接得到ascii了。 2个字符,得到的数据开始是byte[],随便加减了。

阅读全文

与udp校验和计算方法相关的资料

热点内容
OVID方法什么意思 浏览:424
锯片铣刀使用方法视频 浏览:783
快速去皱纹方法图片 浏览:955
回奶的问题和解决方法 浏览:49
费用与效益分析的方法 浏览:36
名师教学方法交流简报 浏览:699
儿童锻炼抵抗力的方法 浏览:592
免费图片点亮的方法 浏览:378
带肋钢筋检测方法 浏览:438
吹水机使用方法 浏览:375
面部肌肉疼痛的治疗方法 浏览:849
颈静脉血栓的最佳治疗方法 浏览:732
运动治疗可以采用哪些方法 浏览:11
什么方法能让宝宝不吃奶 浏览:584
奇异果的种植方法 浏览:622
哮喘早期怎样治疗方法 浏览:32
糖尿病的中医治疗方法 浏览:884
小米笔记本mac地址怎么设置在哪里设置方法 浏览:427
建筑楼梯支模测量方法 浏览:57
猪棚制作方法视频 浏览:907