程序员人生 网站导航

[置顶] TCP/IP入门(3) --传输层

栏目:互联网时间:2015-04-23 07:41:38

/**

本篇博客由汗青ZJF整理并发布, 转载请注明出处:

http://blog.csdn.net/zjf280441589/article/category/1854365

*/

传输层的主要功能

    1)传输层为利用进程之间提供端到端的逻辑通讯(网络层是为主机到主机提供逻辑通讯)。

    2)复用和分用: 复用是指发送方不同的利用进程都可使用同1个传输层协议传送数据; 分用是指接收方的传输层在剥去报文的首部以后能够把这些数据正确交付到目的利用进程.

    3)传输层还会对收到的报文进行过失检测(首部和数据部份), 而网络层只检查IP数据报的首部, 不检验数据部份是不是出错。

    4)传输层需要有两种不同的运输协议:面向连接的传输控制协议 TCP (Transmission Control Protocol)和无连接的用户数据报协议 UDP (User Datagram Protocol);

 

流量控制与堵塞控制的区分

    流量控制常常是指在发送端和接收端之间的点对点通讯量的控制. 流量控制所要做的是抑制发送端发送数据的速率, 以便使接收端来得及接收; 而堵塞控制必须确保通讯子网能够传送待传送的数据, 是1个全局性的问题, 触及网络中所有的主机、路由器和致使网络传输能力降落的所有因素.

 

端口

    端口就是传输层的服务访问点, 用1个 16位的数字进行标标记。

    端口号只具有本地意义,即端口号只是为了标志本计算机利用层中的各进程。在因特网中不同计算机的相同端口号是没有联系的。

    端口的作用是让利用层的各种利用进程都能将其数据通过端口向下交付给传输层,和让传输层知道应当将其报文段中的数据向上通过端口交付给利用层的哪一个进程。

    从这个意义上讲,端口是用来标志利用层的进程;

 

经常使用端口号

利用程序

echo

ftp

ssh

telnet

smtp

端口号

7

20,21

22

23

25

利用程序

dns

dhcp

tftp

http

pop3

端口号

53

67, 68

69

80

110

 

TCP VS UDP

1)TCP

    TCP是1种面向连接的(1对1),提供可靠交付全双工通讯的,基于字节流的端到端传输层通讯协议。

    面向连接: TCP在传输数据之前必须先建立连接,数据传输结束后要释放连接。

    1对1: 每条TCP连接只能有2个端点,故TCP不提供广播或多播服务。

    可靠交付: TCP提供可靠交付,通过TCP连接传输的数据,无过失、不丢失、不重复、并且按序到达。

    基于字节流: TCP是面向字节流的。虽然利用进程和TCP的交互是1次1个数据块(大小不等),但TCP把利用程序交下来的数据仅仅看成是1连串的无结构的字节流, 而其实不知道所传输的字节流的含义。

 

2)UDP

    UDP是1种无连接的,尽最大努力交付的全双工通讯的,基于报文的端到端传输层通讯协议。

    无连接: UDP在发送数据之前不需要建立连接

    尽最大努力交付: UDP不保证可靠交付,主机不需要保持复杂的连接状态

    面向报文: UDP是面向报文的。UDP对利用层交下来的报文,既不合并,也不拆分,而是保存这些报文的的边界,即利用层交给UDP多长的报文,UDP就照样发送,即1次发送1个报文。在接收端,UDP1次交付1个完全的报文, 因此利用程序需要选择适合的报文大小。

其他:

    UDP没有堵塞控制,网络出现的堵塞不会使源主机的发送速率下降。

    UDP支持1对1、1对多、多对1和多对多的交互通讯。

    UDP的首部开消小,只有8个字节,比TCP的20个字节的首部要短。

 

3)区分

TCP

UDP

面向连接

无连接

传输速度慢

传输速度快

保证数据有序到达

不保证数据有序到达

保证数据正确性

可能丢包

TCP报文段

UDP用户数据报

系统资源要求多(需要内核保护发送/接受缓冲区)

要求少(不需要内核保护缓冲区, 直接将数据报发送到网络上, 或直接交付给进程)

适用于对效力要求相对低,但对准确性要求相对高的场景下,或是有1种连接概念的场景(如HTTP服务)

适用于对效力要求相对高,对准确性要求相对低的场景(如视频点播)


UDP数据报

 

UDP有两个字段: 首部字段和数据字段。

首部字段很简单,只有8个字节,由4个字段组成,每一个字段的长度都是两个字节。

源端口

在需要对方回信时选用。不需要时可用全0

目的端口号

这在终点交付报文时必须要使用到

UDP长度

UDP用户数据报的长度,其最小值是8(唯一首部)

UDP校验和

检测UDP用户数据报在传输中是不是有错。有错就抛弃

 

UDP校验

    UDP首部中校验和的计算方法有些特殊。在计算校验和时,要在UDP用户数据报之前增加12个字节的伪首部。伪首部既不向下传送也不向上递交,而仅仅是为了计算校验和。与IP数据报的校验和只校验IP数据报的首部不同,UDP的校验和是把首部和数据部份1起都校验。


    在计算检验和时,临时把“伪首部”和 UDP 用户数据报连接在1起。伪首部仅仅是为了计算检验和, 示例以下:

 

    在发送方,首先是把全零放入校验和字段并且添加伪首部。然后,把UDP数据报看成是由许多16位的字串联接起来。若UDP数据报的数据部份不是偶数个字节,则要在数据部份末尾增加1个全零字节(但此字节不发送)。接下来就按2进制反码计算出这些16位字的和。将此和的2进制反码写入校验和字段。在接收方,把收到的UDP数据报加上伪首部(如果不为偶数个字节,还需要补上全零字节)后,按2进制反码计算出这些16位字的和。当无过失时其结果应全为1。否则就表明有过失出现,接收方就应当抛弃这个UDP数据报。


TCP报文段

协议描写

源端口/目的端口

源/目的主机的IP地址加上端口号构成1个TCP连接(Socket)

序号和确认号

序号为该TCP数据包的第1个字节在所发送的数据流中的偏移量;确认号为希望接收的下1个数据字节的序号;

数据偏移(首部长度)

以4个字节为单位,通常为20个字节

6个标志位:

 

    URG

如果使用了紧急指针,URG置1,紧急指针为当前序号到紧急数据位置的偏移量(经常使用于发送/接受带外数据)

    ACK

为1表示确认号有效,为0表示该TCP数据包不包括确认信息

    PSH

表示是带有PUSH标志的数据,接收到数据后没必要等缓冲区满再发送(较少使用)

    RST

置为1时表示TCP连接中出现了严重的过失, 必须释放连接, 然后重建连接, 也可用于谢绝非法的数据或谢绝连接要求

    SYN

用于建立连接,连接要求时SYN=1,ACK=0;响应连接要求时SYN=1,ACK=1

    FIN

用于释放连接,表示发送方已没有供发送的数据

窗口大小

用来让对方设置发送窗口的大小(用于流量控制)

校验和

校验和覆盖了全部数据包,包括对数据包的首部和数据

紧急指针

指出本报文段中紧急指针共占用多少个字节(紧急数据放在本报文段数据的最前面)

选项

常见的选项是MSS(Maximum Segment Size, 最大报文长度)

填充字段

为了使全部首部为4字节整数倍


TCP3次握手

为何需要采取3次握手?

    主要是为了避免两次握手情况下已失效的连接要求报文段突然又传送到服务端,而产生毛病。举例以下:

    客户A向服务器B发出TCP连接要求,第1个连接要求报文在网络的某个节点长时间滞留,A超时后认为报文丢失,因而再重传1次连接要求,B收到后建立连接。数据传输终了后双方断开连接。而此时,前1个滞留在网络中的连接要求到达了服务端B,而B认为A又发来连接要求,若采取的是“两次握手”,则这类情况下B认为传输连接已建立,并1直等待A传输数据,而A此时并没有连接要求,因此不予理会,这样就造成了B的资源白白浪费了;但此时若是使用“3次握手”,则B向A返回确认报文段,由因而1个失效的要求,因此A不予理会,建立连接失败。第3次握手的作用:避免已失效的连接要求报文段突然传送到了服务器

 

3次握手进程

 

 

    1)第1次握手:客户机的TCP首先向服务器的TCP发送1个连接要求报文段。这个特殊的报文段中不含利用层数据,其首部中的SYN标志位被置为1。另外,客户机会随机选择1个起始序号seq=x(连接要求报文不携带数据,但要消耗掉1个序号)。

    2)第2次握手:服务器的TCP收到连接要求报文段后,犹如意建立连接,就向客户机发回确认,并在OS内核中为该TCP连接分配TCP缓存和变量。在确认报文段中,SYN和ACK位都被置为1,确认号字段的值为x+1(表示希望收到的下1个字节的序号为x+1),并且服务器随机产生起始序号seq=y(确认报文不携带数据,但也要消耗掉1个序号)。

    3)第3次握手:当客户机收到确认报文段后,还要向服务器给出确认,并且也要在client真个OS内核中给该连接分配缓存和变量。这个报文段的ACK标志位被置1,序号字段为x+1,确认号字段为y+1。

    需要注意的是:服务器真个资源是在完成第2次握手时分配的,而客户真个资源是在完成第3次握手时分配的。这就使得服务器易于遭到SYN洪泛攻击。

 

TCP4次断开

 

    1)第1次断开:客户机打算关闭连接,就向其TCP发送1个连接释放报文段,并停止发送数据,主动关闭TCP连接,该报文段的FIN标志位被置1,seq=u,它等于前面已传送过的数据的最后1个字节的序号加1(FIN报文段即便不携带数据,也要消耗掉1个序号)。

    2)第2次断开:服务器收到连接释放报文段后即发出确认,确认号是ack=u+1,而这个报文段自己的序号是v,等于它前面已传送过的数据的最后1个字节的序号加1。此时,从客户机到服务器这个方向的连接就释放了,TCP连接处于半关闭状态。但服务器若发送数据,客户机仍要接收,即从服务器到客户机这个方向的连接并未关闭

    3)第3次断开:若服务器已没有要向客户机发送的数据,就通知TCP释放连接,此时其发出FIN=1的连接释放报文段(注意: 此时确认号字段值仍为u+1, 由于这段时间里, 客户端并未发送任何数据到服务器)。

    4)第4次断开:客户机收到连接释放报文段后,必须发出确认。在确认报文段中,ACK字段被置为1,确认号ack=w+1,序号seq=u+1。此时TCP连接还没有释放掉,必须经过时间等待计时器设置的时间2MSL后,A才进入到连接关闭状态。

 

TIME_WAIT状态

    1)为了保证客户端发送的最后1个ACK报文段能够到达服务器。 这个ACK报文段可能丢失,因此使处在LAST_ACK状态的服务器收不到确认。这样的话, 服务器超时重传FIN+ACK报文段,客户端就可以在2MSL时间内收到这个重传的FIN+ACK报文段,接着客户端重传1次确认,重启计时器。最后,客户端和服务器都正常进入到CLOSED状态。

    如果客户端在TIME_WAIT状态不等待1段时间,而是在发送完ACK报文后立即释放连接,那末就没法收到服务器重传的FIN+ACK报文段,因此也不会再发送1次确认报文。这样,服务器就没法依照正常步骤进入CLOSED状态。

    2)避免已失效的连接要求报文段出现在本连接中。客户端在发送完最后1个ACK确认报文段后,再经过时间2MSL,就能够使本连接延续的时间内所产生的所有报文段都从网络中消失。这样就能够使下1个新的连接中不会出现这类旧的连接要求报文段。

    注意:服务器结束TCP连接的时间要比客户端早1些,由于客户机(最早提出close要求的1端)最后要等待2MSL后才可以进入CLOSED状态。


TCP如何保证可靠性

    序号: TCP连接中传送的数据流中的每个字节都编上1个序号。序号字段的值则指的是本报文段所发送的数据的第1个字节的序号;

    确认: TCP首部的确认号是期望收到对方的下1个报文段数据的第1个字节的序号。当数据发送出去以后, 发送方缓存区会继续存储那些已发送但未收到确认的报文段,以便在需要的时候重传。TCP默许使用累计确认,即TCP只确认数据流中至第1个丢失字节为止的字节。

    重传: 有两种事件会致使TCP对报文段进行重传:超时和冗余ACK

        1)超时: TCP每发送1个报文段,就对这个报文段设置1次计时器。只要计时器设置的重传时间到期但还没有收到确认,就要重传这1报文段。

        2)冗余ACK(冗余确认): 冗余ACK就是再次确认某个报文段的ACK,而发送方先前已收到过该报文段的确认; TCP规定当发送方收到对同1个报文段的3个冗余ACK时,就能够认为跟在这个被确认报文段以后的报文段已丢失;

    校验: TCP将保持它首部和数据的校验和。这是1个端到真个校验和,目的是检测数据在传输进程中的任何变化。如果收到段的校验和有过失,TCP将抛弃这个报文段并且不确认(致使对方超时重传);

    重排: TCP承载于IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。TCP将对收到的数据进行重新排序。IP数据报会产生重复,TCP的接收端会抛弃重复的数据。

    流量控制: TCP还能提供流量控制。TCP连接的每方都有1定大小的缓冲空间。

    分割: 利用数据被分割成TCP认为最合适发送的数据块,称为TCP报文段传递给IP层。

 

滑动窗口协议与停止等待协议的区分

    滑动窗口协议中,允许发送方发送多个分组(当有多个分组可用时), 而不需等待确认,但它受限于在流水线中未确认的分组数不能超过某个最大允许数N。

    滑动窗口协议是TCP使用的1种控制流量的方法,此协议能够加速数据的传输。 只有在接收窗口向前滑动时(与此同时也发送了确认), 发送窗口才有可能向前滑动。收发两真个窗口依照以上规律不断地向前滑动,因此这类协议称为滑动窗口协议。

    当发送窗口和接收窗口的大小都等于1时,就是停止等待协议


TCP流量控制

    TCP提供了流量控制服务以消除发送方使接收方缓存区溢出的可能性,因此可以说流量控制是1个速度匹配服务(匹配发送方的发送速率与接收方的读取速率)。

    在通讯进程中,接收方根据自己接收缓存的大小,动态地调剂发送方的发送窗口大小,这就是接收窗口rwnd,即调剂TCP报文段首部中的“窗口”字段值,来限制发送方向网络注入报文的速率。同时,发送方根据其对当前网络堵塞程序的估计而肯定的窗口值,称为堵塞窗口cwnd,其大小与网络的带宽和时延密切相干。

 

滑动窗口

    TCP 采取大小可变的滑动窗口进行流量控制(窗口大小的单位是字节), 在 TCP 报文段首部的窗口字段写入的数值就是当前给对方设置的发送窗口数值的上限。

    发送窗口在连接建立时由双方约定。但在通讯的进程中,接收端可根据自己的资源情况,随时动态地调剂对方的发送窗口上限值(可增大或减小)。

 

发送进程及详细分析

    1)发送端要发送 900 字节长的数据,划分为 9 个 100 字节长的报文段,而发送窗口肯定为 500 字节。 发送端只要收到了对方的确认,发送窗口便可前移。发送 TCP 要保护1个指针。每发送1个报文段,指针就向前移动1个报文段的距离。

 

    2)发送端已发送了 400 字节的数据,但只收到对前 200 字节数据的确认,同时窗口大小不变。现在发送端还可发送 300 字节(401~700)。

 

    3)发送端收到了对方对前 400 字节数据的确认,但对方通知发送端必须把窗口减小到 400 字节。现在发送端最多还可发送 400 字节(401~800)的数据。

 


利用可变窗口大小进行流量控制(双方肯定的窗口值是 400)

(101~200的数据产生丢失)


慢开始和堵塞避免

1. 发送真个主机在肯定发送报文段的速率时,既要根据接收真个接收能力,又要从全局斟酌不要使网络产生堵塞。因此,每个 TCP 连接需要有以下两个状态变量:

    接收窗口 rwnd (receiver window): 这是接收端根据其目前的接收缓存大小所许诺的最新的窗口值,是来自接收真个流量控制。接收端将此窗口值放在 TCP 报文的首部中的窗口字段,传送给发送端。

    堵塞窗口 cwnd (congestion window): 是发送端根据自己估计的网络堵塞程度而设置的窗口值,是来自发送真个流量控制。

    发送真个发送窗口的上限值应当取为接收端窗口 rwnd 和堵塞窗口 cwnd 这两个变量中较小的1个,即应按以下公式肯定:

        发送窗口的上限值 = Min(rwnd, cwnd)

 

2. 慢开始算法

    在TCP刚刚连接好,开始发送TCP报文段时,先令堵塞窗口cwnd=1,即1个最大报文段长度MSS。而在每收到1个对新的报文段的确认后,将cwnd加1,即增大1个MSS。用这样的方法逐渐增大发送方的堵塞窗口cwnd,可使分组注入到网络的速率更加公道。

    使用慢开始算法后,每经过1个传输轮次(即来回时延RTT),堵塞窗口cwnd就会加倍,即cwnd的大小呈指数情势增长(可以看出”慢开始”其实不”慢”)。这样慢开始1直把堵塞窗口cwnd增大到1个规定的慢开始门限ssthresh(阈值),然后改用堵塞避免算法。

 

3. 堵塞避免算法

    发送真个堵塞窗口cwnd每经过1个来回时延RTT就增加1个MSS的大小,而不是加倍(不同于慢开始算法),使cwnd按线性规律缓慢增长(即加法增大),而当出现1次超时(网络堵塞)时,则令慢开始门限ssthresh等于当前cwnd的1半(即乘法减小)

根据cwnd的大小履行不同的算法,可归纳以下:

        当cwnd<ssthresh时,使用慢开始算法。

        当cwnd>ssthresh时,停止使用慢开始算法而改用堵塞避免算法。

        当cwnd=ssthresh时,既可以使用慢开始算法,也可以使用堵塞避免算法(通常做法)。

 

4.网络堵塞的处理

    当网络出现堵塞时,不管在慢开始阶段还是在堵塞避免阶段,只要发送方检测到超时事件的产生(没有按时收到确认,重传计时器超时),就要把慢开始门限ssthresh设置为出现堵塞时的发送方cwnd值的1半(但不能小于2)。然后把堵塞窗口cwnd重新设置为1,履行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得产生堵塞的路由器有足够时间把队列中积存的分组处理终了。

    堵塞避免并不是完全能避免堵塞。利用以上措施要完全避免网络堵塞是不可能的。堵塞避免是指在堵塞避免阶段把堵塞窗口控制为按线性规律增长,使网络比较不容易出现堵塞。

    慢开始和堵塞避免算法的实现进程以下图所示:

    注意,在慢开始(指数级增长)阶段,若2*cwnd>ssthresh,则下1个RTT的cwnd应等于ssthresh,而不是2*cwnd,即cwnd不能跃过ssthresh值。

 

小结:

    在慢开始和堵塞避免算法中使用了“乘法减小”和“加法增大”方法。“乘法减小”是指不论在慢开始阶段还是堵塞避免阶段,只要出现1次超时(即极可能出现了网络堵塞),就把慢开始门限值ssthresh设置为当前的堵塞窗口值的1半。当网络频繁出现堵塞时,ssthresh值就降落得很快,以大大减少注入到网络中的分组数。而“加法增大”是指履行堵塞避免算法后,在收到对所有报文段的确认后(即经过1个RTT),就把堵塞窗口cwnd增加1个MSS大小,使堵塞窗口缓慢增大,以避免网络过早出现堵塞。


快重传与快恢复

    快重传和快恢复算法是对慢开始和堵塞避免算法的改进。

1.快重传

    当发送方连续收到3个重复的ACK报文时,直接重传对方还没有收到的报文段,而没必要等待那个报文段设置的重传计时器超时。

 

2.快恢复

    快恢复算法原理:当发送端收到连续3个冗余ACK(即重复确认)时,就履行“乘法减小”算法,把慢开始门限ssthresh减半。与慢开始(慢开始算法将堵塞窗口cwnd设置为1)不同的地方是它把cwnd的值设置为慢开始门限ssthresh减半后的数值,然后开始履行堵塞避免算法(“加法增大”),使堵塞窗口缓慢地线性增大。

    由于跳过了cwnd从1起始的慢开始进程(由于既然现在能够收到3个重复ACK确认, 就说明堵塞程序其实不是很大),所以被称为快恢复。快恢复算法的实现进程以下图所示,作为对照,虚线为慢开始的处理进程。

 

 

 

    注-发送方发送窗口的实际大小由流量控制堵塞控制共同决定。因此,当同时出现了接收端窗口(rwnd)和堵塞窗口(cwnd)时,发送方实际的发送窗口大小是由rwnd和cwnd中较小的那1个肯定的。

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐