如何udp实现可靠数据传输TCP和UDP传输

扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
用Socket实现基于TCP和UDP的原理探索
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口IP、ICMP、UDP、TCP 校验和算法分享
这篇文章主要是为探索一下这个校验和算法具体怎么实现的,需要的朋友可以参考下
以前看计算机网络相关的书,每次看到IP或者UDP报头校验和时,都一瞥而过,以为相当简单,不就是16bit数据的相加吗。最近在研究《TCP/IP详解 卷1:协议》这本书,看到校验和是16bit字的二进制反码和(晕,以前都没注意原来是反码和,看来以前看书不仔细啊!罪过,罪过~~),觉得很奇怪,为什么会用反码和,而不是直接求和呢?(因为我认为TCP/IP协议里面的算法和思想一般都是非常经典的,人家这么做一定有原因的)下面就来探索一下这个校验和算法具体怎么实现的。
&首先,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时溢出,这样也可以说明为什么<font color="#ff和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 plaincopy//计算校验和
USHORT checksum(USHORT *buffer,int size)
unsigned long cksum=0;
while(size&1)
cksum+=*buffer++;
size-=sizeof(USHORT);
cksum+=*(UCHAR *)
//将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,嘿嘿 结果第二篇就是我想要的文章了!!!先把链接给大家吧:/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整个首部进行重新计算。当然,可能从汇编语言的角度看,反码求和还有很多高效的地方,这里就不在深入追究了~~~结语:本来一个不怎么注意的地方,深入探究一下竟然发现这么多东西。学习算法其实没有必要抱着《算法导论》一页一页地啃(嘿嘿,哥也有一本哦),我更喜欢从 TCP/IP协议或LInux内核原理中去探究算法以及实现思想,这样反倒更有趣,而且这里面的一些算法和思想相当经典,慢慢体会,必然受益匪浅!您所在的位置: &
2.1.3 IP、TCP和UDP协议(1)
2.1.3 IP、TCP和UDP协议(1)
陈文/郭依正
机械工业出版社
《深入理解Android网络编程:技术详解与最佳实践》第2章Android基本网络技术和编程实践,本章主要介绍计算机网络的相关概念,包括TCP/IP分层模型及IP、TCP、UDP等主要协议。在此基础上,重点阐述在Android中如何使用TCP和UDP进行通信。最后,给出Android Socket编程的一个实际案例。本节为大家介绍IP、TCP和UDP协议。
2.1.3 IP、TCP和UDP协议(1)
由于OSI/RM模型过于复杂也难以实现,现实中广泛应用的是TCP/IP模型。TCP/IP是一个协议集,是由ARPA于1977年到1979年推出的一种网络体系结构和协议规范。随着Internet的发展,TCP/IP也得到进一步的研究开发和推广应用,成为Internet上的&通用语言&。
TCP/IP模型也是分层模型,分为4层。OSI/RM模型与TCP/IP模型的参考层次如图2-1所示。
TCP/IP模型4层分述如下。
应用层:应用层是大多数普通与网络相关的程序为了通过网络与其他程序通信所使用的层。在应用层中,数据以应用内部使用的格式进行传送,然后被编码成标准协议的格式。重要的例子如万维网使用的HTTP协议、文件传输使用的FTP协议、接收电子邮件使用的POP3和IMAP协议、发送邮件使用的SMTP协议,以及远程登录使用的SSH和Telnet等。所以用户通常是与应用层进行交互。
传输层:传输层响应来自应用层的服务请求,并向网络层发出服务请求。传输层提供两台主机之间透明的数据传输,通常用于端到端连接、流量控制或错误恢复。这一层的两个最重要的协议是TCP(Transmission Control Protocol,传输控制协议)和UDP(User Datagram Protocol,用户数据报协议)。
网络层:网络层提供端到端的数据包交付,换言之,它负责数据包从源发送到目的地,任务包括网络路由、差错控制和IP编址等。这一层包括的重要协议有IP(版本4和版本6)、ICMP(Internet Control Message Protocol,Internet控制报文协议)和IPSec(Internet Protocol Security,Internet协议安全)。
网络接口层:是TCP/IP参考模型的最底层,负责通过网络发送和接收IP数据报;允许主机连入网络时使用多种现成的与流行的技术,如以太网、令牌网、帧中继、ATM、X.25、DDN、SDH、WDM等。
一个应用层应用一般都会使用到两个传输层协议之一:面向连接的TCP传输控制协议和面向无连接的UDP用户数据报协议。下面分析TCP/IP协议栈中常用的IP、TCP和UDP协议。
互联网协议(Internet Protocol,IP)是用于报文交换网络的一种面向数据的协议。IP是在TCP/IP协议中网络层的主要协议,任务是根据源主机和目的主机的地址传送数据。为达到此目的,IP定义了寻址方法和数据报的封装结构。第一个架构的主要版本,现在称为IPv4,仍然是最主要的互联网协议,如图2-2所示。当前世界各地正在积极部署IPv6。
下面对IPv4协议包的结构进行介绍,包含多个数据域。各个数据域的含义如下。
4位版本:表示目前的协议版本号,数值是4表示版本为4,因现在主要使用的还是版本为4的IP协议,所以IP有时也称为IPv4。
4位首部长度:头部的长度,它的单位是32位(4字节),数值为5表示IP头部长度为20字节。
8位服务类型(TOS):这个8位字段由3位的优先权子字段(现在已经被忽略)、4位的TOS子字段以及1位的未用字段(现在为0)构成。4位的TOS子字段包含最小延时、最大吞吐量、最高可靠性以及最小费用构成,对应位为1时指出上层协议对处理当前数据报所期望的服务质量。如果都为0,则表示是一般服务。
16位总长度(字节数):总长度字段是指整个IP数据报的长度,以字节为单位。如数值为00 30,换算成十进制为48字节,48字节=20字节的IP头+28字节的TCP头。这个数据报只是传送的控制信息,还没有传送真正的数据,所以目前看到的总长度就是报头的长度。【责任编辑: TEL:(010)】&&&&&&
关于&&的更多文章
这是一本Android网络编程方面的专著,旨在帮助开发者们高效地编
本书描述了黑客用默默无闻的行动为数字世界照亮了一条道路的故事。
多年来,Imar Spaanjaars一直是ASP.NET相关图书的畅销
《C#高级编程(第8版)》是C# 2012和.NET 4.5高级技术的
《Android 4 游戏入门经典(第3版)》将赋予您惊人的灵
本书详细描述如何在复杂技术项目中使用Scrum,并结合真实的Scrum案例及专家洞识,在简明及高度概括的理论之上更侧重于实践,并不
51CTO旗下网站

我要回帖

更多关于 tcp udp 的文章

 

随机推荐