跟我学TCP/IP系列5

    前面四篇文章大致写完了TCP/IP的大部分内容,今天恰好有空,又给可爱的小伙伴们写推文了。按照现在的知识点分类的话,应该还两到三篇的文章,今天这篇会讲讲TCP和UDP异同以及TCP的三次握手和四次挥手,相关的保证TCP高效传输的机制,文章有点长,希望各位读者可以耐心读完。下一章会和大家分享一下路由协议的相关知识,敬请期待。

TCP/UDP简介


1传输层的作用

    TCP/IP中有两个具有代表性的传输层协议,分别是TCP和UDP。TCP提供面向连接的可靠的通信传输,而UDP则提供面向无连接的不可靠的通信传输,UDP常被用于让广播和细节控制交给应用的通信传输。所以在使用时要根据通信的具体特征,选择合适的传输层协议。


传输层的定义

    在跟我学TCP/IP系列3中提到,IP首部中有一个协议字段,用来标识网络层(IP)的上一层所采用的是哪一种传输层协议,根据这个字段的协议号,就可以识别IP传输的数据部分内容是TCP的还是UDP的。同样,传输层的TCP和UDP为了识别自己所传输的数据部分究竟应该转发给哪个应用,也设置了这样一个编号。

通信处理

    TCP/IP的众多应用协议中大多以客户端/服务器端的形式运行,客户端用于发起请求而服务器端则表示提供服务的意思,也就是请求的处理端。另外服务端必须先于客户端启动,准备接收客户端的请求。

跟我学TCP/IP系列5_第1张图片

HTTP连接请求

    由于现在的服务器大部分是以Linux搭建的,这些服务端程序在Linux中被当做守护进程来使用。在Linux上不需要将这些进程逐个启动,而是启动一个可以代表他们接收客户端请求的inetd(互联网守护进程)服务程序即可。它是一个超级守护进程,该超级守护进程接收到客户端请求后会创建新的进程并转换为sshd,httpd等守护进程。


两种传输层协议

TCP/UDP

    TCP是面向连接的、可靠的流协议,流(比如水流啊)就是指一种不间断的数据结构。当程序采用TCP发送消息时,虽然可以保证发送的顺序,但是好像没有任何间隔的数据流发送给接收端。TCP为提供可靠的传输,实现顺序控制和重发机制,此外还有流量控制,拥塞控制、提高网络利用率等功能。

    UDP是不具有可靠性的数据报协议,细微的处理它会交由上层的应用去完成。在UDP的情况下,虽然可以确保发送消息的大小,但是不能保证消息一定会到达。因此应用有时会根据自己的需要进行重发处理。

TCP与UDP的区别

    既然前面说TCP比UDP可靠,那么TCP就一定会优于UDP吗?其实随便想想也知道,既然UDP到现在都还活着,肯定有他自己独特的优点啊。

    TCP主要用于在传输层有必要实现可靠传输的情况,优于是面向有连接并具备顺序控制,重发机制等,所以它可以提供可靠的传输。而UDP主要用于那些对高数传输和实时性有较高要求的通信或者广播通信(比如视频会议、IP电话进行通话、广播、多播等)。


2端口???

端口

    前面说过,数据链路和IP中的地址,分别指的是MAC地址和IP地址。前者用来识别同一链路中不同的计算机,后者用于识别TCP/IP网络中互连测主机和路由器。在传输层中的端口号也就是很类似于地址的抽象概念。端口号用来识别同一台PC中进行通信的不同应用程序,也被称为程序地址。前一段时间爆发的勒索病毒啊,就是通过通过所谓的445之类的端口入侵的,445端口常常用作共享端口,用过Linux的同学们都知道Samba这个服务器,Samba就是通过445端口在不同的操作系统之间传输文件的。

跟我学TCP/IP系列5_第2张图片

根据端口号识别应用

    But,仅仅通过端口号就可以识别某一个通信了吗?让我们来看张图开心一下

跟我学TCP/IP系列5_第3张图片

识别多个请求

图中1,2的通信是在两台PC上进行的,而且目标端口都是80。图1和3中目标端口号和源端口号完全一样,但是各自的源IP地址不同。还有一种情况在图中未给出,就是IP地址和端口号全一样,只有协议号不同,也会被认为是不同的两个通信。

    因此TCP/IP或UDP/IP中通过5个信息来识别一个通信,分别是源IP地址,目标IP地址,协议号,源端口好,目标端口号。只要上述的5个信息有一个或者一个以上不相同则被认为是不一样的通信。


如何确定端口号?确定端口号有两种方法:

    标准既定的端口号:也被称为静态方法,是指每个应用程序都有其指定的端口号,但并不可以随便使用任何一个端口号。每一个端口号都有其对应的使用目的。知名端口号一般由0-1023的数字组成,应用程序应该避免使用知名端口号进行既定目的之外的通信,以免产生冲突。除知名端口号在,剩下的分别在1024-49151之间,这些端口可用作任何通信用途。

    时序分配法:也叫动态分配法,此时服务器有必要确定监听端口号,但是接收服务的客户端没有必要确定端口号。根据这种动态分配端口号的机制,即使是同一个客户端发起的多个TCP连接,识别这些通信的5部分数字也不会全部相同。动态分配的端口号地址范围在49152到65535之间。


3UDP简述

UDP

    UDP(User Datagram Protocol)即用户数据报协议,UDP不提供复杂的控制机制,利用IP提供面向无连接的通信服务,并且是将应用程序发来的数据在接收到的那一刻,立即按照原样发送到网络上的一种机制。即使是在出现网络拥堵的情况下,UDP也无法进行流量控制等避免网络拥塞的行为。此外即使出现丢包的情况,UDP也不进行重发。对于乱序的包也无纠错能力。若需要实现对这些细节的控制,可以交由UDP的应用程序去处理。

    由于UDP采用面向无连接,它可以随时发送数据,再加上UDP本身的处理既简单又高效,因此经常用于处理以下的几个方面通信:

1、包总量较少的通信(DNS,SNMP等)

2、视频、音频等多媒体通信(即时通信)

3、限定于LAN等特定网络中的应用通信

4、广播通信(广播、多播)


4TCP简述

    TCP则充分实现了数据传输时各种控制功能,可以进行丢包时的重发控制,对乱序包进行顺序控制等。TCP作为一种面向有连接的协议,只有在确认通信端存在时才会发送数据,从而可以避免流量的浪费。TCP通过校验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。


TCP

    与面向无连接的UDP不同,面向有连接的TCP提供了一系列可靠的机制来提供更安全的传输服务。首先是通过序列号与确认应答提高可靠性:

    在TCP中,当发送端的数据到达接收主机时,接收端会返回一个已收到消息的通知,叫做确认应答(ACK);TCP通过肯定的确认应答实现可靠的数据传输,当发送端将数据发送出去以后会等待对端的确认应答。如果有确认应答,说明数据已经成功到达对端,反之,则数据丢失的可能性很大。

跟我学TCP/IP系列5_第4张图片

正常的数据传输

    当在一个时间段没有等到确认应答,发送端就可以认为数据已经丢失,并进行重发,由此即使产生了丢包,仍然可以保证数据到达对端实现可靠的数据传输。

跟我学TCP/IP系列5_第5张图片

丢失发送的数据包

    未收到确认应答并不意味着数据一定丢失,也有可能是数据对方接受到了数据但是在返回ACK时在途中丢失。此时发送端没有接收到确认应答而认为没有到达目的地,从而进行重发。

    此外,也有可能因为其他原因导致确认应答延迟到达,在源主机重发数据以后才到达的情况也很常见。此时源发送主机只要按照重发机制进行重发即可。

    上述的这些确认应答处理,重发控制,以及重复控制等功能都可以通过序列号实现,序列号是按顺序给发送数据的每一个字节(8位字节)都标上号码编号,接收端查询接受数据TCP首部中的序列号和数据的长度,将自己下一辈应该接受的序列号作为确认应答发送回去。就这样,通过序列号和确认应答号,TCP可以实现可靠传输。

跟我学TCP/IP系列5_第6张图片

发送数据


超时重发机制

    超时重发是指在重发数据之前,等待确认应答到来的那个特定时间间隔,如果超过了这个时间仍未收到确认应答,发送端将进行数据重发。那超时重发的具体时间长度要怎样计算呢?

    TCP要求不论处在何种环境下都要提供高性能通信,并且无论网络拥堵情况发生何种变化,都必须保持这一特定。为此,TCP在每次发包时都会计算往返时间及其偏差。将这个往返时间和偏差相加超时重发的时间,就是比这个总和要稍微大一点的值。重发时间是否需要需要同时考虑往返时间和偏差呢?看看下图可知,网络环境的不同可能会产生大幅度的摇摆,之所以发生这种情况是因为数据包的分段是经过不同线路到达的,TCP/IP的目的是即使在这种环境下也要进行控制,尽量不浪费网络流量。

跟我学TCP/IP系列5_第7张图片

往返时间的计算和重发超时的推移

    数据被重发之后若还是收不到确认应答,则进行再次重发,此时等待确认应答的时间将会以2倍、4倍的指数函数延长。同时数据也不会被无限,反复地重发。到达一定重发次数以后,如果仍没有确认应答返回,就会判断为对网络或对端主机发生了异常,强制关闭连接,并通知应用通信异常强行终止。


连接管理

    TCP提供面向有连接的通信传输,面向有连接是指在数据通信开始之前先做好通信两端之间的准备工作。TCP在数据通信之前,通过TCP首部发送一个SYN包作为建立连接的请求等待确认应答。如果对端发来确认应答,则认为可以进行数据通信。若应答未能到达,就不会进行数据通信。

跟我学TCP/IP系列5_第8张图片

TCP建立与断开连接

这就是我们常说的TCP的三次握手和四次挥手,由于上图不是很容易理解,我去偷了一张图,给大家看看更容易看懂的TCP的建立与断开连接的过程。

跟我学TCP/IP系列5_第9张图片

其实在建立与断开连接时也是要靠序列号才能进行的,所以,我又偷了一张图。

跟我学TCP/IP系列5_第10张图片

三次握手

第一次握手:

客户端发送一个TCP的SYN标志位置1的包指明客户打算连接的服务器的端口,以及初始序号X,保存在包头的序列号(Sequence Number)字段里。

第二次握手:
服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1同时,将确认序号(Acknowledgement Number)设置为客户的I S N加1以.即X+1。

第三次握手:

客户端再次发送确认包(ACK) SYN标志位为0,ACK标志位为1.并且把服务器发来ACK的序号字段+1,放在确定字段中发送给对方.并且在数据段放写ISN的+1。

再来一张开心一下:

跟我学TCP/IP系列5_第11张图片

四次挥手

客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。

第一次挥手:

客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。 

第二次挥手:

服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。 

第三次挥手:

服务器B关闭与客户端A的连接,发送一个FIN给客户端A。 

第四次挥手:

客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。

认真理解上面的几张图,相信你很快就懂了。


发送单位

    TCP以段为单位发送数据,在建立TCP连接的同时,也可以确定发送数据包的单位,我们可以称之为“最大消息长度(MSS:Maxumum Segment Size)”。最理想的就是最大消息长度正好是IP中不会被分片处理的最大数据长度。

    TCP在传送大量数据时,是以MSS的大小将数据进行分割发送,进行重发时也是以MSS为单位。MSS是在三次握手的时候再两端主机之间被计算出,两端主机在发出建立连接的请求时,会在TCP首部中写入MSS选项,告知对方自己的接口能够适应的MSS的大小,然后会在两者之间选择一个较小的值投入使用。

跟我学TCP/IP系列5_第12张图片

225_2.png

接入以太网主机与接入FDDI主机之间的通信情况


滑动窗口

    TCP以一个段为单位,每发一个段进行一次确认应答的处理,但这种传输方式缺点很大,包的往返时间越长通信性能就越低,这样效率也低。因此提出了一种窗口发送方式:确认应答不再是以每个分段,而是以更大的单位进行确认,转发时间也被发福缩短。

跟我学TCP/IP系列5_第13张图片

滑动窗口方式进行并行处理

窗口的大小就是指无需等待确认应答而可以继续发送数据的最大值,在上图中窗口大小为4个段。

跟我学TCP/IP系列5_第14张图片

滑动窗口方式

    在上图中,数据高亮圈起的部分就是前面所说的窗口,在这个窗口内的数据即便没有收到确认应答也可以发送出去。此外,从该

窗口中能看到的数据因其某种数据已在传输中丢失,所以发送端才能收到确认应答,这种情况也需要重发,所以发送端主机在等到确认应答返回时,必须在缓冲区中保留这部分数据。

    在滑动窗口以外的部分包括尚未发送的数据以及确认对端已收到的数据,当数据发出后若如期收到确认应答就不用再进行重发,此时数据就可以从缓存中清除。

    收到确认应答的情况下,将窗口滑动到确认应答中序列号的位置。这样也可以顺序地将多个段同时发送提高通信性能,这种机制也称为滑动窗口机制。


窗口控制与重发机制

    若在窗口控制中出现段丢失怎么办?首先看看确认未能返回的情况,在这种情况下,数据已经到达对端是不需要进行重发的,然而在没有窗口控制的时候,未收到确认应答的数据都会被重发的,而使用窗口控制也就简化了重发的处理。

跟我学TCP/IP系列5_第15张图片

确认应答未能返回

    其次,若报文段丢失的情况,接收主机如果收到一个自己应答序号以外的数据时,会针对当前为止收到的数据返回确认应答。但如下图所示,在报文段丢失后,发送端一直收到序号1001的确认应答。因此在窗口比较大,又出现报文段丢失的情况下,同一序号的确认将会被重发不断地返回,而发送端主机如果连续三次收到同一个确认应答,就会将其所对应的数据进行重发,这种机制比以前的超时管理更加高效,也被称为高速重发控制。

跟我学TCP/IP系列5_第16张图片

高速重发控制


流控制和拥塞控制

    TCP提供了一种机制可以让发送端根据接收端的实际接收能力控制发送的数据量,这就是所谓的流控制。它的具体操作就是接收端想发送端主机通知自己可以接收数据的大小,于是发送端会发送不超过这个限度的数据,该大小限度就被称为是窗口大小。

跟我学TCP/IP系列5_第17张图片

流控制

    在TCP首部中,专门有一个字段用来通知窗口大小,接受主机将自己可以接收的缓冲区大小放入这个字段中通知给发送端。这个字段的值越大,说明网络的吞吐量越高。不过,接收端的这个缓冲区一旦面临数据溢出时,窗口大小的值也会随之被设置为一个更小的值通知给发送端,从而控制数据发送量。也就是说,发送端主机会根据接收端主机的指示,对发送数据的量进行控制。这也就形成了一个完整的TCP流控制(流量控制);


拥塞控制

    有了TCP的窗口控制,收发主机之间即使不再以一个数据段为单位发送确认应答,也能够连续发送大量数据包,然而如果再通信刚开始时就发送大量数据也会引发其他问题。TCP为防止该问题的出现,在通信一开始时就会通过一个叫做慢启动的算法得出的数值,对发送数据量进行控制。

    首先,为了在发送端调节所要发送的数据量,定义了一个叫做拥塞窗口的概念,于是在慢启动的时候,将拥塞窗口的大小设置为1个数量端发送数据,之后每收到一个ACK,拥塞窗口的值就加1。

在发送数据包时,将拥塞窗口的大小与接收端主机通知的窗口大小做比较,然后按照它们当中比较小的那个值,发送比其还要小的数据量。

    如果采用超时重发机制,那么拥塞窗口的初始值可以设置为1以后再进行慢启动修正,有了上述这些机制就可以有效地减少通信开始时连续发包导致的网络拥堵,还可以避免网络拥塞情况的发生。

    不过大家想想也知道,随着包的每次往返,拥塞窗口也会以1,2,4等指数函数的增长,拥堵情况激增甚至导致网络拥塞的发生。为了防止这些,引入了慢启动阈值的概念,只有拥塞窗口的值超过了这个阈值,就会按下面的公式进行窗口调整:1个数据段的字节数/拥塞窗口(字节)*1个数据段字节数。

跟我学TCP/IP系列5_第18张图片

TCP的窗口变化

跟我学TCP/IP系列5_第19张图片

慢启动

    拥塞窗口越大,确认应答的数目也会增加,不过随着每收到一个确认应答,其涨幅也会逐渐减少,甚至小过比一个数据段还要小的字节数。所以,拥塞窗口的大小会呈直线上升的趋势。TCP通信开始时,并没有设置相应的慢启动阈值,而是在超时重发时才会设置为当时拥塞窗口一般的大小。


    这大体上就是整个TCP和UDP的介绍了,其中着重介绍了TCP的三次握手和四次挥手以及一些相应的控制机制。如果文中有不对的地方欢迎读者指正。如果有什么疑问也可以在后台给我留言,我会尽我所知回答每一位读者的问题。

你可能感兴趣的:(Android)