目录
简介
UDP是一种没有复杂控制,提供面向无连接通信服务的一种协议。换句话 说,它将部分控制转移给应用程序去处理,自己却只提供作为传输层协议的最基 本功能。
与UDP不同,TCP则”人如其名“,可以说是对“传输、发送、通信”进行 “控制”的"协议”。
TCP与UDP的区别相当大。它充分地实现了数据传输时各种控制功能,可以 进行丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。而这些在UDP 中都没有。此外,TCP作为一种面向有连接的协议,只有在确认通信对端存在时 才会发送数据,从而可以控制通信流量的浪费。
根据TCP的这些机制,在IP这种无连接的网络上也能够实现高可靠性的 通信。
连接
连接是指各种设备、线路,或网络中进行通信的两个应用程序为了 相互传递消息而专有的、虚拟的通信线路,也叫做虚拟电路。
一旦建立了连接,进行通信的应用程序只使用这个虚拟的通信线路 发送和接收数据,就可以保障信息的传输。应用程序可以不用顾虑提供 尽职服务的IP网络上可能发生的各种问题,依然可以转发数据。TCP则 负责控制连接的建立、断开、保持等管理工作。
TCP的特点及其目的
为了通过IP数据报实现可靠性传输,需要考虑很多事情,例如数据的破坏、 丢包、重复以及分片顺序混乱等问题。如不能解决这些问题,也就无从谈起可靠 传输。
TCP通过检验和、***、确认应答、重发控制、连接管理以及窗口控制等 机制实现可靠性传输。
通过***与确认应答提高可靠性
在TCP中,当发送端的数据到达接收主机时,接收端主机会返回一个已收到消息的通知。这个消息叫做确认应答(ACK)。
通常,两个人对话时,在谈话的停顿处可以点头或询问以确认谈话内容。如果对方迟迟没有任何反馈,说话的一方还可以再重复一遍以保证对方确实听到。因此,对方是否理解了此次对话内容,对方是否完全听到了对话的内容,都要靠对方的反应来判断。网络中的“确认应答”就是类似这样的一个概念。当对方听懂对话内容时会说: “嗯”,这就相当于返回了一个确认应答(ACK)。而当对方没有理解对话内容或没有听清时会问一句“咦?”这好比一个否定确认应答 (NACK)
TCP通过肯定的确认应答(ACK)实现可靠的数据传输。当发送端将数据发 出之后会等待对端的确认应答。如果有确认应答,说明数据已经成功到达对端。 反之,则数据丢失的可能性很大。
在一定时间内没有等到确认应答,发送端就可以认为数据已 经丢失,并进行重发。由此,即使产生了丢包,仍然能够保证数据能够到达对端, 实现可靠传输。
未收到确认应答并不意味着数据一定丢失。也有可能是数据对方已经收到, 只是返回的确认应答在途中丢失。
这种情况也会导致发送端因没有收到确认应答, 而认为数据没有到达目的地,从而进行重新发送。
此外,也有可能因为一些其他原因导致确认应答延迟到达,在源主机重发数 据以后才到达的情况也履见不鲜。此时,源发送主机只要按照机制重发数据即可。 但是对于目标主机来说,这简直是一种“灾难”。它会反复收到相同的数据。而 为了对上层应用提供可靠的传输,必须得放弃重复的数据包。为此,就必须引入一种机制,它能够识别是否已经接收数据,又能够判断是否需要接收。
上述这些确认应答处理、重发控制以及重复控制等功能都可以通过***实现。
***是按顺序给发送数据的每一个字节(8位字节)都标上号码的编号。接收端查询接收数据TCP首部中的***和数据的长度,将自己下一步应该接收的序号作为确认应答返送回去。就这样,通过***和确认应答号, TCP可以实现可靠传输。
重发超时如何确定
重发超时是指在重发数据之前,等待确认应答到来的那个特定时间间隔。如 果超过了这个时间仍未收到确认应答,发送端将进行数据重发。那么这个重发超 时的具体时间长度又是如何确定的呢?
最理想的是,找到一个最小时间,它能保证”确认应答一定能在这个时间内 返回"。然而这个时间长短随着数据包途径的网络环境的不同而有所变化。例如 在高速的LAN中时间相对较短,而在长距离的通信当中应该比LAN要长一些, 即使是在同一个网络中,根据不同时段的网络拥堵程度时间的长短也会发生变化。
TCP要求不论处在何种网络环境下都要提供高性能通信,并且无论网络拥堵 情况发生何种变化,都必须保持这一特性。为此,它在每次发包时都会计算往返 时间及其偏差。将这个往返时间和偏差相加重发超时的时间,就是比这个总和要稍大一点的值。
重发超时的计算既要考虑往返时间又要考虑偏差是有其原因。根据网络环境的不同往返时间可能会产生大幅度的摇摆,之所以发生这种情 况是因为数据包的分段是经过不同线路到达的。TCP/IP的目的是即使在这种环境 下也要进行控制,尽量不要浪费网络流量。
在BSD的Unix以及Windows系统中,超时都以0.5秒为单位进行控制,因此 重发超时都是0.5秒的整数倍。不过,由于最初的数据包还不知道往返时间, 所以其重发超时一般设置为6秒左右。
数据被重发之后若还是收不到确认应答,则进行再次发送。此时,等待确认应答的时间将会以2倍、4倍的指数函数延长。
此外,数据也不会被无限、反复地重发。达到一定重发次数之后,如果仍没 有任何确认应答返回,就会判断为网络或对端主机发生了异常,强制关闭连接。 并且通知应用通信异常强行终止。
连接管理(3次握手,4次挥手)
TCP提供面向有连接的通信传输。面向有连接是指在数据通信开始之前先做 好通信两端之间的准备工作。
UDP是一种面向无连接的通信协议,因此不检查对端是否可以通信,直接将 UDP包发送出去。TCP与此相反,它会在数据通信之前,通过TCP首部发送一个 SYN包作为建立连接的请求等待确认应答。如果对端发来确认应答,则认为可 以进行数据通信。如果对端的确认应答未能到达,就不会进行数据通信。此外, 在通信结束时会进行断开连接的处理(FIN包)。
可以使用TCP首部用于控制的字段来管理TCP连接。
一个连接的建立与断 开,正常过程至少需要来回发送7个包才能完成。
注意:主机B握手的ACK和SYN在一个包里。主机B挥手的ACK和FIN不在一个包里,因为B当时可能还有东西要发送,发送完毕,才会发送FIN。
TCP以段为单位发送数据
在建立TCP连接的同时,也可以确定发送数据包的单位,我们也可以称其为 “最大消息长度" (MSS: Maximum Segment Size)。最理想的情况是,最大消息长 度正好是IP中不会被分片处理的最大数据长度。
TCP在传送大量数据时,是以MSS的大小将数据进行分割发送。进行重发时 也是以MSS为单位。
MSS是在三次握手的时候,在两端主机之间被计算得出。
两端的主机在发出 建立连接的请求时,会在TCP首部中写入MSS选项,告诉对方自己的接口能够适 应的MSS的大小。然后会在两者之间选择一个较小的值投人使用。
利用窗口控制提高速度
TCP以1个段为单位,每发一个段进行一次确认应答的处理,这 样的传输方式有一个缺点。那就是,包的往返时间越长通信性能就越低。
为解决这个问题,TCP引人了窗口这个概念。即使在往返时间较长的情况下, 它也能控制网络性能的下降。确认应答不再是以每个分段,而是以 更大的单位进行确认时,转发时间将会被大幅度的缩短。也就是说,发送端主机, 在发送了一个段以后不必要一直等待确认应答,而是继续发送。
窗口大小就是指无需等待确认应答而可以继续发送数据的最大值。图,窗口大小为4个段。
这个机制实现了使用大量的缓冲区,通过对多个段同时进行确认应答的 功能。
发送数据中高亮圈起的部分正是前面所提到的窗口。在这个 窗口内的数据即便没有收到确认应答也可以发送出去。此外,从该窗口中能看到 的数据因其某种数据已在传输中丢失,所以发送端才能收到确认应答,这种情况 也需进行重发。为此,发送端主机在等到确认应答返回之前,必须在缓冲区中保 留这部分数据。
在滑动窗口以外的部分包括尚未发送的数据以及巳经确认对端已收到的数据。
当数据发出后若如期收到确认应答就可以不用再进行重发,此时数据就可以从缓 存区清除。
收到确认应答的情况下,将窗口滑动到确认应答中的***的位置。这样可 以顺序地将多个段同时发送提高通信性能。这种机制也被称为滑动窗口控制。
窗口控制与重发控制
在使用窗口控制中,如果出现段丢失该怎么办?
首先,我们先考虑确认应答未能返回的情况。在这种情况下,数据已经到达 对端,是不需要再进行重发的。然而,在没有使用窗口控制的时候,没有收到确 认应答的数据都会被重发。而使用了窗口控制,某些确认应答 即便丢失也无需重发。
其次,我们来考虑一下某个报文段丢失的情况。接收主机如果收到一个自己应该接收的序号以外的数据时,会针对当前为止收到数据返回确 认应答。
当某一报文段丢失后,发送端会一直收到序号为1001的确 认应答,这个确认应答好像在提醒发送端“我想接收的是从1001开始的数据“。 因此,在窗口比较大,又出现报文段丢失的情况下,同一个序号的确认应答将会 被重复不断地返回。而发送端主机如果连续3次收到同一个确认应答,就会将 其所对应的数据进行重发。这种机制比之前提到的超时管理更加高效,因此也被 称作高速重发控制。
流控制
发送端根据自己的实际情况发送数据。但是,接收端可能收到的是一个毫无 关系的数据包又可能会在处理其他问题上花费一些时间。因此在为这个数据包做 其他处理时会耗费一些时间,甚至在高负荷的情况下无法接收任何数据。如此一 来,如果接收端将本应该接收的数据丢弃的话,就又会触发重发机制,从而导致 网络流量的无端浪费。
为了防止这种现象的发生,TCP提供一种机制可以让发送端根据接收端的实 际接收能力控制发送的数据量。这就是所谓的流控制。它的具体操作是,接收端 主机向发送端主机通知自己可以接收数据的大小,于是发送端会发送不超过这个 限度的数据。该大小限度就被称作窗口大小。窗口大 小的值就是由接收端主机决定的。
TCP首部中,专门有一个字段用来通知窗口大小。接收主机将自己可以接收 的缓冲区大小放入这个字段中通知给发送端。这个字段的值越大,说明网络的吞 吐量越高。
不过,接收端的这个缓冲区一旦面临数据溢出时,窗口大小的值也会随之被 设置为一个更小的值通知给发送端,从而控制数据发送量。也就是说,发送端主 机会根据接收端主机的指示,对发送数据的量进行控制。这也就形成了一个完整 的TCP流控制(流量控制)。
当接收端收到从3001号开始的数据段后其缓冲区即满,不 得不暂时停止接收数据。之后,在收到发送窗口更新通知后通信才得以继续进行。 如果这个窗口的更新通知在传送途中丢失,可能会导致无法继续通信。为避免此 类问题的发生,发送端主机会时不时的发送一个叫做窗口探测的数据段,此数据 段仅含一个字节以获取最新的窗口大小信息。
拥塞控制
有了TCP的窗口控制,收发主机之间即使不再以一个数据段为单位发送确认 应答,也能够连续发送大量数据包。然而,如果在通信刚开始时就发送大量数据, 也可能会引发其他问题。
一般来说,计算机网络都处在一个共享的环境。因此也有可能会因为其他主 机之间的通信使得网络拥堵。在网络出现拥堵时,如果突然发送一个较大量的数 据,极有可能会导致整个网络的瘫痪。
TCP为了防止该问题的出现,在通信一开始时就会通过一个叫做慢启动的算 法得出的数值,对发送数据量进行控制。
首先,为了在发送端调节所要发送数据的量,定义了一个叫做“拥塞窗口” 的概念。
于是在慢启动的时候,将这个拥塞窗口的大小设置为1个数据段 (1 MSS)发送数据,之后每收到一次确认应答(ACK), 拥塞窗口的值就加1。
在发送数据包时,将拥塞窗口的大小与接收端主机通知的窗口大小做比较,然后 按照它们当中较小那个值,发送比其还要小的数据量。
如果重发采用超时机制,那么拥塞窗口的初始值可以设置为1以后再进行慢 启动修正。有了上述这些机制,就可以有效地减少通信开始时连续发包1,导致的 网络拥堵,还可以避免网络拥塞情况的发生。
不过,随着包的每次往返,拥塞窗口也会以1、2、4等指数函数的增长,拥 堵状况激增甚至导致网络拥塞的发生。为了防止这些,引入了慢启动阀值的概念。
只要拥塞窗口的值超出这个阀值,在每收到一次确认应答时,只允许以下面这种 比例放大拥塞窗口:
拥塞窗口越大,确认应答的数目也会增加。不过随着每收到一个确认应答,其涨幅也会逐渐减少,甚至小过比一个数据段还要小的字节数。因此,拥塞窗口的大小会呈直线上升的趋势。
TCP的通信开始时,并没有设置相应的慢启动阀值。
而是在超时重发时,才会设置为当时拥塞窗口一半的大小。
由重复确认应答而触发的高速重发与超时重发机制的处理多少有些不同。
因为前者要求至少3次的确认应答数据段到达对方主机后才会触发,相比后者网络的拥堵要轻一些。
而由重复确认应答进行高速重发控制时,慢启动阀值的大小被设置为当时窗口大小的一半。然后将窗口的大小设置为该慢启动阀值+3个数据段的大小。
有了这样一种控制, TCP的拥塞窗口如图所示发生变化。由于窗口的大小会直接影响数据被转发时的吞吐量,所以一般情况下,窗口越大,越会形成高吞吐量的通信。当TCP通信开始以后,网络吞吐量会逐渐上升,但是随着网络拥堵的发生吞吐量也会急速下降。于是会再次进入吞吐量慢慢上升的过程。因此所谓TCP的吞吐量的特点就好像是在逐步占领网络带宽的感觉。
提高网络利用率的规范
Nagle算法
TCP中为了提高网络的利用率,经常使用一个叫做Nagle的算法。
该算法是指发送端即使还有应该发送的数据,但如果这部分数据很少的话, 则进行延迟发送的一种处理机制。具体来说,就是仅在下列任意一种条件下才能 发送数据。如果两个条件都不满足,那么暂时等待一段时间以后再进行数据发送。
- 已发送的数据都已经收到确认应答时
- 可以发送最大段长度(MSS)的数据时
根据这个算法虽然网络利用率可以提高,但是可能会发生某种程度的延迟。
为此,在窗口系统”以及机械控制等领域中使用TCP时,往往会关闭对该算法的 启用。
延迟确认应答
接收数据的主机如果每次都立刻回复确认应答的话,可能会返回一个较小的窗口。那是因为刚接收完数据,缓冲区已满。
当某个接收端收到这个小窗口的通知以后,会以它为上限发送数据,从而又 降低了网络的利用率。为此,引人了一个方法,那就是收到数据以后并不立即 返回确认应答,而是延迟一段时间的机制。
- 在没有收到2x最大段长度的数据为止不做确认应答(根据操作系统的不 同,有时也有不论数据大小,只要收到两个包就即刻返回确认应答的 情况。)
- 其他情况下,最大延迟0.5秒发送确认应答(很多操作系统设置为0.2 秒左右)
事实上,大可不必为每一个数据段都进行一次确认应答。TCP采用滑动窗口 的控制机制,因此通常确认应答少一些也无妨。TCP文件传输中,绝大多数是每 两个数据段返回一次确认应答。
捎带应答
根据应用层协议,发送出去的消息到达对端,对端进行处理以后,会返回一 个回执。例如,电子邮件协议的SMTP或POP、文件传输协议FTP中的连接控制 部分等。这些应用协议使用同一个连接进行数据的交互。即使是 使用WWW的HTTP协议,从1.1版本以后也是如此。再例如远程登录中针对输 入的字符进行回送校验,也是对发送消息的一种回执。
在此类通信当中,TCP的确认应答和回执数据可以通过一个包发送。这种方 式叫做捎带应答 (PiggyBack Acknowledgement)。通过这种机制,可以使收发的 数据量减少。
另外,接收数据以后如果立刻返回确认应答,就无法实现捎带应答。而是将 所接收的数据传给应用处理生成返回数据以后进再进行发送请求为止,必须一直 等待确认应答的发送。也就是说,如果没有启用延迟确认应答就无法实现捎带应 答。
延迟确认应答是能够提高网络利用率从而降低计算机处理负荷的一种较优的 处理机制。
使用TCP的应用
CP采用这些机制可以提供高速、可 靠的通信服务。
不过,有时这些机制也会受其一定缺陷的困扰。为此,在开发应用的时候, 有必要考虑一下是全权交给TCP去处理好,还是由应用自已进行更细微的控 制好。
如果需要应用自己处理一些更为细节上的控制,使用UDP协议是不错的选 择。
如果转发数据量较多、对可靠性的要求比较高时,可以选择使用TCP。
TCP 和UDP两者各有长短,在设计和开发应用时,应准确掌握它们各自协议的特点酌 情选择。