TCP UDP 相关

一、UDP

主要特点:【不可靠的传输】

(1)无连接:发送数据之前不需要建立连接,发送结束也没有连接需要释放,减少了开销和发送数据之前的时延
(2)尽最大努力交付,不保证可靠交付,主机不需要维持复杂的连接状态表。
(3)面向报文。保留应用层交下来的报文边界,即UDP一次交付一个完整的报文,报文过短或过长,都可能会降低IP层效率。
(4)没有拥塞控制,网络出现拥塞不会使源主机发送速率降低。适用于实时应用。很多实时应用要求源主机已恒定的速率发送数据,允许网络拥塞时丢失一些数据,但不允许数据有太大时延。
弊端:很多源主机同时向网络发送高速率的实时视频流时,网络可能发生拥塞,大家都无法进行接收。
(5)UDP支持一对一、一对多、多对一、多对多的交互通信。

(6)UDP首部开销小,只有8字节,TCP最少需要20字节。

(7)UDP支持的应用层协议主要有:NFS(网络文件系统)、SNMP(简单网络管理协议)、DNS(主域名称系统)、TFTP(通用文件传输协议)等。

二、TCP

1、主要特点:面向连接的可靠服务、流量控制、拥塞控制
(1)面向连接:使用TCP协议之前需要建立TCP连接,传送数据之后,必须释放已经建立的连接。【打电话】
(2)TCP连接只能是一对一
(3)提供可靠交付服务。无差错、不丢失、不重复、按顺序到达。
(4)提供全双工通信。允许通信双方的应用进程在任何时候都能发送数据。TCP连接的两端都设有发送缓存和接收缓存,临时存放双向通信的数据。
(5)面向字节流。TCP中的流是指流入到进程或从进程流出的字节序列。TCP把数据看成一连串无结构的字节流。

(6)TCP根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少字节。数据块太长,就划分短一些再传送。如果太短,可以等待积累长了再发。

(8)TCP支持的应用层协议主要有:Telnet、FTP、SMTP等。

2、TCP建立连接:三次握手

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

【注】未连接队列:
在三次握手协议中,服务器维护一个未连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于SYN_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。


3、TCP释放连接:四次挥手

第一步,当主机A的应用程序通知TCP数据已经发送完毕时,TCP向主机B发送一个带有FIN附加标记的报文段(FIN表示英文finish)。

第二步,主机B收到这个FIN报文段之后,并不立即用FIN报文段回复主机A,而是先向主机A发送一个确认序号ACK,同时通知自己相应的应用程序:对方要求关闭连接

(先发送ACK的目的是为了防止在这段时间内,对方重传FIN报文段,在接下来的时间进行未完成的数据传送)。【主机A进入FIN_WAIT】

第三步,主机B的应用程序告诉TCP:我要彻底的关闭连接,TCP向主机A送一个FIN报文段。

第四步,主机A收到这个FIN报文段后,向主机B发送一个ACK表示连接彻底释放。【主机A进入TIME_WAIT】主机B收到ACK就知道可以断开连接了。

TIME_WAIT:

在TIME_WAIT状态中,如果TCP 主机A最后一次发送的ACK丢失了,它将重新发送。TIME_WAIT状态中所需要的时间是依赖于实现方法的。典型的值为30秒、1分钟和2分钟。等待之后连接正式关闭,并且所有的资源(包括端口号)都被释放。

4、为什么连接的时候是三次握手,关闭的时候却是四次握手?

        因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

5、为什么TIME_WAIT状态需要经过2*MSL(最大报文段生存时间)才能返回到CLOSE状态?

        虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。主机A的 ACK 报文丢失时,主机B会重发 FIN 的。主机A收到主机B重发的 FIN ,会再发一个 ACK,同时重置计时器。MSL 远大于主机B的超时时间,所以主机B超时后会重发 FIN ,但没超过 2*MSL。

6、为什么是三次握手,两次不行吗?

        三次握手可以防止已失效的连接请求报文段突然又传送到服务端,产生错误。即客户端发送的第一个连接请求报文段并没有丢失,而是在某个网络节点长时间滞留了,以致延误到连接释放的某个时间才到达服务端。这是一个失效的报文段,但是服务端误以为是一个新的连接请求,向客户端发送确认报文段。如果采用两次握手,则建立了新的连接,服务端一直等待客户端发送数据,但是由于客户端并没有请求建立新的连接,也就没有数据传送,这样会浪费掉很多服务端资源。但是三次握手就避免了这个问题,因为客户端不会发送确认报文段,连接也就没有建立。

7、TCP保证可靠传输:

(1)应用数据被分割成TCP认为最适合发送的数据块。TCP在三次握手建立连接过程中,会在SYN报文中使用MSS(Maximum Segment Size)选项功能,协商交互双方能够接收的最大段长MSS值。发送窗口(TCP中发送方可发送的最大数据)的大小由窗口值和拥塞窗口值共同确定。

(2) TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。 (校验出包有错,丢弃报文段,不给出响应,TCP发送数据端,超时时会重发数据)。

(3)超时重传机制:当TCP发出一个数据后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。在未收到确认之前,这些已经发送的数据报将留在发送缓冲区,直到收到确认之后才清除已发送的数据。

(4)既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。如果必要,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层。

(5)TCP还能提供流量控制。TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据。这将防止较快主机致使较慢主机的缓冲区溢出。因为一旦有一方来不及接受数据,势必会造成数据的丢失。

(6)拥塞控制:当网络拥塞时,减少数据的发送。

8、TCP流量控制:

        滑动窗口协议:是TCP使用的一种流量控制方法。该协议允许发送方在停止并等待确认前可以连续发送多个分组。由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输。TCP中采用滑动窗口来进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区可以用于接收数据。发送方可以通过滑动窗口的大小来确定应该发送多少字节的数据。当滑动窗口为0时,发送方一般不能再发送数据报。

9、TCP拥塞控制:
    拥塞控制是通过拥塞窗口处理网络拥塞现象的一种机制。

(1)慢启动和拥塞避免

慢启动: 
  发送方维护一个拥塞窗口cwind的状态变量。拥塞窗口的大小取决于网络的拥塞程度,动态变化。通过逐渐增加cwind的大小来探测可用的网络容量,防止连接开始时采用不合适的发送量导致网络拥塞。 
  [1]. 当主机开始发送数据时,如果通过较大的发送窗口立即将全部数据字节都注入到网络中,由于不清楚网络情况,有可能引起网络拥塞; 
  [2]. 较好方法是试探,从小到达逐渐增大发送端拥塞控制窗口的cwind数值; 
  [3]. 开始发送报文段时,先将拥塞窗口cwind设置为一个最大报文段MSS值。每收到一个对新报文段的ACK确认后,将拥塞窗口cwind增加至多一个MSS的数值。当rwind足够大的时候,为防止拥塞窗口cwind的增长引起网络拥塞,还需要另外一个变量,慢开始门限ssthresh。 
    当 cwind < ssthresh时,使用上述慢启动算法; 
    当 cwind > ssthresh时,停止使用慢启动算法,改用拥塞避免算法;


拥塞避免: 

  让拥塞窗口cwind缓慢地增大,每经过一个往返时间RTT就把发送方的拥塞窗口cwind加1,而不是加倍。这样拥塞窗口cwind线性缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多。 
  无论慢启动开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢启动门限ssthresh设置为出现拥塞时的发送方窗口值的一半(但不能小于2)。然后把拥塞窗口cwind重新设置为1,执行慢启动算法。目的是迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。

    

        TCP UDP 相关

说明:由指数增长拉低到线性增长,降低出现拥塞的可能。“拥塞避免”并非指完全能够避免拥塞,利用以上的措施要完全避免网络拥塞还是不可能的。 慢开始算法只是在TCP连接建立和网络出现超时时才使用。

(2)快重传和快恢复

       如果发送方设置的超时计时器时限已到但还没有收到确认,很可能是网络出现了拥塞。

    当TCP源端收到到三个相同的ACK确认时,即认为有数据包丢失,则源端重传丢失的数据包,而不必等待 RTO(Retransmission Timeout)超时。由于发送方尽早重传未被确认的报文段,因此,采用快重传后可以使整个网络吞吐量提高约20%。

控制过程: 
 与快重传配合使用的还有快恢复算法,具体地: 
     [1]. 当发送方连续收到三个重复确认时,执行“乘法减小”算法,慢启动门限减半,为了预防网络发生拥塞。 
     [2]. 由于发送方现在认为网络很可能没有发生拥塞,因此现在不执行慢启动算法,而是把cwind值设置为慢启动门限减半后的值,然后开始执行拥塞避免算法,拥塞窗口cwind值线性增大。避免了当网络拥塞不够严重时采用”慢启动”算法而造成过大地减小发送窗口尺寸的现象。

TCP UDP 相关

(3)总结

慢启动局限性: 
[1]. 需要获得网络内部流量分布的信息,浪费可用的网络容量,额外开销; 
[2]. 估算合理的ssthresh值并不容易,可能耗时较长;

  慢启动的“慢”并不是指cwind的增长速度慢,而是指在TCP开始发送报文段时先设置cwind=1,使得发送方在开始时只发送一个报文段(目的是探测一下网络的拥塞情况),然后再逐渐增大cwind。


注:借鉴包含但不限于以下博客

http://blog.****.net/li_ning_/article/details/52117463###;

http://blog.****.net/dr_neo/article/details/52400544

http://blog.****.net/qq_18425655/article/details/52163228

http://blog.****.net/whuslei/article/details/6667471

http://blog.****.net/qing101/article/details/48653797