五、运输层
5.1TCP
5.1.1TCP和UDP区别?
1) TCP面向连接,UDP无连接;
2) TCP保证数据的可靠传输,数据传送无差错,不丢失,无重复,按序到达;
3) TCP连接点对点单播,UDP 支持单播、多播、广播;
4) UDP 设计简单,实时性好,效率高,适用于很多应用,如:多媒体应用等;
TCP 设计复杂,用于大多数应用,如:万维网、电子邮件、文件传送等。
5) TCP面向数据流, UDP面向数据报。
5.1.2TCP如何实现可靠传输?
TCP 提供了面向字节的差错控制。
TCP 提供了面向字节的流量控制。发送 TCP 要对能接受多少从发送进程传来的字节进行控制;接收 TCP 则要对发送 TCP 能够发送多少字节进行控制。
TCP 提供了拥塞控制。发送方允许发送的数据量不仅要受接收方的控制(流量控制),而且还要由网络的拥塞状况来决定。
5.1.3什么是确认重传机制?
在发送一个数据之后,就开启一个定时器,若是在这个时间内没有收到发送数据的ACK确认报文,则对该报文进行重传,在达到一定次数还没有成功时放弃并发送一个复位信号。
A.累计确认
累计确认就是TCP协议的确认方法,TCP使用可变长度报文段来发送数据,重传时, 报文段数据可能会比原报文段数据包含更多的数据,因此对数据报和报文段无法进行简单的确认。TCP使用流序号对流中的一个位置进行确认,即序号和确认号--对应, 接收方使用序号将报文段重新排序,且以正确接收到的流的最长连续前缀确认。
B.超时重传
超时时间计算是开启定时器的设定时间,从而保证网络资源利用率,避免因定时器的时间(RTO)不确定而影响网络传输效率。
C.快速重传
后面拥塞控制章节会讲。
5.1.4为什么要流量控制?
通信双方在数据传输时,发送方的速率与接收方的速率是不一定相等,如果发送方的发送速率太快,会导致接收方处理不过来,这时候接收方只能把处理不过来的数据存在缓存区里(失序的数据包也会被存放在缓存区里)。
如果缓存区满了发送方还在疯狂着发送数据,接收方只能把收到的数据包丢掉,大量的丢包会极大着浪费网络资源,因此,我们需要控制发送方的发送速率,让接收方与发送方处于一种动态平衡才好。
故对发送方发送速率的控制,我们称之为流量控制。
5.1.5什么是滑动窗口协议?
我们在TCP如何实现可靠传输一章中说道TCP实现有序传输采用了确认应答机制,如果通信双发仅接收到一帧,确认一帧,再发送一帧,实现简单的停止等待协议。那么整个网络的吞吐量将会非常的低。
滑动窗口协议用于网络数据传输时的流量控制,以避免拥塞的发生。 该协议允许发送方在停止并等待确认前发送多个数据分组。由于发送方不必每发-个分组就停下来等待确认,因此该协议可以加速数据的传输,提高网络吞吐量。
它本质上是描述接收方数据报缓冲区大小的数据,发送方根据这个数据来计算自己最多能发送多长的数据。这个窗口大小为0时,发送方将停止发送数据。启动定时器,等待这个窗口变成非0。
滑动窗口协议必须保证数据包的按序传输,发送窗口中的序列号代表已发送但尚未收到确认的数据包,发送窗口可持续地维持一系列未经确认的数据包,因为发送方窗口内的数据包可能在传输过程中丢失或损坏,所以发送过程必须把发送窗口中的所有数据包保存起来以备重传。发送窗口一旦达到最大值,发送过程就必须停止接收新的数据包,直到有空闲缓存区。
接收窗口外的数据包都要丢弃,当序列号等于接收窗口下限的数据包到达时,把它提交给应用程序并向发送端发送确认,接收窗口向前移动一位。发送窗口和接收窗口上下限无需相同,大小也无需相同,但接收窗口大小需保持固定,发送窗口大小可随着数据包而改变。如何控制1)接收方ACK报文会携带窗口信息,发送方收到之后,便会调整自己的发送速率,也就是调整自己发送窗口的大小;
2)发送方接收到rwnd==0的报文后停止发送,并启动定时器,每隔- -段时间就发个测试报文去询问接收方接收窗口大小,即等待接收方rwnd>0的报文。
5.1.5.1接收窗口大小是否固定?
TCP是双工的协议,会话双方都可以同时接收、发送数据。TCP会话双方都各自维护一个发送窗口和一个接收窗口,各自的接收窗口大小取决于应用、系统、硬件的限制。当链路变好或者变差,这个窗口会 发生变化。
PS: 在早期的TC协议中,接受接受窗口的大小确实是固定的,不过随着网络的快速发展,固定大小的窗口太不灵活了,成为TCP性能瓶颈之。
5.1.5.2接收窗口越大越好吗?
接受窗口如果太小的话,显然这是不行的,这会严重浪费链路利用率,增加丢包率。那是否越大越好呢?答否,当接收窗口达到某个值的时候,再增大的话也不怎么会减少丢包率的了,而且还会更加消耗内存。所以接收窗口的大小必须根据网络环境以及发送发的的拥塞窗口来动态调整。
5.1.5.3接收双发窗口大小是否相等?
接收方在发送确认报文的时候,会告诉发送发自己的接收窗口大小,而发送方的发送窗口会据此来设置自己的发送窗口,但这并不意味着他们就会相等。首先接收方把确认报文发出去的那一刻,就已经在-边处理堆在自己缓存区的数据了,所以一般情况下接收窗口>=发送窗口。
5.1.6TCP如何进行拥塞控制的?
所谓拥塞控制,就是提高网络利用率,降低丢包率并保证网络资源的对每条数据流的公平性。拥塞控制是-一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络传输性能有关的所有因素。
拥塞控制的几个主要方法包括:慢启动、拥塞避免、快速重传和快速恢复。
慢开始并非指拥塞窗口(cwnd) 在过程中增长的慢,而是启动时把拥塞窗口设置为一-个最大报文段MSS的数值。而在每收到一个对新的报文段的确认后,把拥塞窗口增加至多一个MSS的数值(即指数增长)。用这样的方法逐步增大发送方的拥塞窗口,可以使分组注入到网络的速率更加合理。
当cwnd增长到一个阈值ssthresh时,就开始使用拥塞避免算法,即每经过一个往返时间RTT就把发送方的cwnd加1,进行线性增长。
以上是发送端在未检测到拥塞时所采用的积极避免拥塞的方法。接下来介绍拥塞发生时(可能发生在慢启动阶段或者拥塞避免阶段)拥塞控制的行为。先来了解-下发送端可以判断拥塞发生的依据:
●传输超时(TCP重传定时器溢出)仍然使用慢启动和拥塞避免算法
做法是把ssthresh置为出现拥塞时的拥塞窗口的一半(但不能小于2) ,以及cwnd置为1进行慢开始。目的是迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。
●接收到重复的确认报文段使用快速重传和快速恢复发送端如果连续收到3个重复的确认报文端,就认为是拥塞发生了,具体实现步骤:
1)快速重传(Fast retransmit): 要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方),而不要等到自己发送数据时捎带确认;
2)快速恢复(Fast retransmit):发送方接收到三个重复ACK报文后,把慢开始门]限ssthresh减半,并将CWND设置为新的ssthresh,然后立即重传丢失的报文段,并开始进行拥塞避免算法。
5.1.7tcp报文格式
由上图中的TCP报文格式可知,TCP报文首部有20字节的固定首部以及最大长度为40字节的偏移数据构成,即TCP报文头部最大60字节(计算方式后面会讲)。
其中固定首部包括:
端口号:包括源端口号和目的端口号两部分,分别占2字节,用来标识同一台计算机的不同的应用进程。
TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接。
序列号和确认号:序号是本报文段发送的数据组的第一个字节的序号。在TCP传送的流中,每一个字节一个序号。
如一个报文段的序号为300,此报文段数据部分共有100 字节,则下一个报文段的序号为400。所以序号确保了TCP传输的有序性。确认号,指下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK标志为1时才有效。比如建立连接时,SYN 报文的ACK标志位为0。
序号和确认号分别占4字节。
数据偏移或首部长度:首部长度也叫数据偏移,因为首部可能含有可选项内容,因此TCP报头的长度是不确定的,首部长度实际上指示了数据区在报文段中的起始偏移值。
由于首部长度只占到了4bit大小,所以能表示的最大长度是2^4-1=15, 同时它的单位是4字节,所以首部最大长度是4*15=60 字
保留:6位
控制位: 6位
包括URG、ACK、PSH、RST、SYN 和FIN六个,每一个标志位表示一个控制功能。
1) URG: 紧急指针标志,为1时表示紧急指针有效, 为0则忽略紧急指针。
2) ACK: 确认序号标志,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段。
3) PSH: push标志,为1表示是带有push标志的数据,指示接收方在接收到该报文段以后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队。
4) RST:重置连接标志,用于重置由于主机崩溃或其他原因而出现错误的连接。或者用于拒绝非法的报文段和拒绝连接请求。
5) SYN:同步序号,用于建立连接过程,在连接请求中,SYN= 1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一 个确认,即SYN= 1和ACK=1。
6) FIN: 结束标志,用于释放连接,为1时表示反送万匕经没有数据友达S,即天团本万数据流。
窗口(2字节):滑动窗口大小,用来告知发送端接受端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。窗口大小是一个1 6bit的字段,因而窗口大小最大为65535。
校验和(2字节):奇偶校验,此校验和是对整个的TCP报文段,包括TCP头部和TCP数据,以16位字进行计算所得。由发送端计算和存储,并由接收端进行验证。
紧急指针(2字节): 只有当URG标志置1时紧急指针才有效。紧急指针是-个正的偏移量,和顺序号字段中的值相加表示紧急数据最后- -个字节的序号。TCP的紧急方式是发送端向另一-端发送紧急数据的一种方式。
选项和填充:最常见的可选字段是最长报文大小,又称为MSS (Maximum Segment Size),每 个连接方通常都在通信的第一个报文段 (为建立连接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。
5.1.8三次握手和四次挥手的过程
三次握手:
①首先 Client 端发送连接请求报文
②Server 段接受连接后回复 ACK 报文,并为这次连接分配资源。
③Client 端接收到 ACK 报文后也向 Server 段发生 ACK 报文,并分配资源,这样 TCP 连接就建立了。
如果只有两次握手 这个时候客户端没有回应,这样会浪费服务端的资源
那你是否思考过为什么需要第三次通信 ?
1、在第一次通信过程中,A向B发送信息之后,B收到信息后可以确认自己的收信能力和A的发信能力没有问题。
2、在第二次通信中,B向A发送信息之后,A可以确认自己的发信能力和B的收信能力没有问题,但是B不知道自己的发信能力到底如何,所以就需要第三次通信。
3、在第三次通信中,A向B发送信息之后,B就可以确认自己的发信能力没有问题。
4、 小结:3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。
TCP的四次挥手:
建立连接非常重要,它是数据正确传输的前提;断开连接同样重要,它让计算机释放不再使用的资源。如果连接不能正常断开,不仅会造成数据传输错误,还会导致套接字不能关闭,持续占用资源,如果并发量高,服务器压力堪忧。
第一次挥手:Clien发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
第二次挥手:Server收到FIN后,发送一个ACK给Client,Server进入CLOSE_WAIT状态。
第三次挥手: Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,发送ACK给Server,Server进入CLOSED状态,完成四次握手。
数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于ESTABLISHED状态,然后客户端主动关闭,服务器被动关闭。
为什么连接的时候是三次握手,关闭的时候却是四次握手?
①因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。
②但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。
③只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
TCP的三次握手一定能保证传输可靠吗?不能
三次握手比两次更可靠,但也不是完全可靠,而追加更多次握手也不能使连接更可靠了。因此选择了三次握手。
世界上不存在完全可靠的通信协议。从通信时间成本空间成本以及可靠度来讲,选择了“三次握手”作为点对点通信的一般规则。
为何不能两次握手进行连接?
三次握手完成了两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。如果把三次握手改成仅需要两次握手,可能会造成死锁是。
如计算机S和C之间的通信,假定C给S发送-个连接请求分组,S收到了这个分组,并发送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据分组。可是,C在S的应答分组在传输中被丢失的情况下,将不知道S是否已准备好,不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。
什么是TCP粘包和拆包?
TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包,从接收缓冲区来看,后-包数据的头紧接着前一包数据的尾,出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方。
为什么会产生这样的现象?
这是由于TCP为提高性能,发送端会将需要发送的数据发送到缓冲区,等待缓冲区满了之后,再将缓冲中的数据发送到接收方。同理,接收方也有缓冲区这样的机制,来接收数据。
而UDP则是面向消息传输的,是有保护消息边界的,接收方-次只接受一条独立的信息,所以不存在粘包问题。
如何处理粘包现象?
1)对于发送方造成的粘包问题,可以通过关闭Nagle算法来解决,使用TCP_ NODEL AY选项来关闭算法;
2)接收方没有办法来处理粘包现象,只能将问题交给应用层来处理;
3)应用层的解决办法简单可行,不仅能解决接收方的粘包问题,还可以解决发送方的粘包问题。
循环处理,应用程序从接收缓存中读取分组时,读完一条数据,就应该循环读取下一条数据,直到所有数据都被处理完成,但是如何判断每条数据的长度呢?
●格式化数据:每条数据有固定的格式(开始符,结束符),这种方法简单易行,但是选择开始符和结束符时一 定要确保每条数据的内部不包含开始符和结束符。
●发送长度:发送每条数据时,将数据的长度一 并发送,例如规定数据的前4位是数据的长度,应用层在处理时可以根据长度来判断每个分组的开始和结束位置。
5.2 UDP
1、UDP 是无连接的,发送数据之前不需要建立连接,因此减少了开销和发送数据之前的时延。
2、UDP 使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态表。
3、UDP 是面向报文的。UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。应用层交给 UDP 多长的报文,UDP 就照样发送。
4、UDP 没有拥塞控制,因此网络出现的拥塞不会使源主机的发送速率降低。这对某些实时应用是很重要的。很适合多媒体通信的要求。
5、UDP 支持一对一、一对多、多对一和多对多的交互通信。
6、UDP 的首部开销小,只有 8 个字节,比 TCP 的 20 个字节的首部要短。
标签:运输,窗口,报文,TCP,发送,拥塞,接收 From: https://www.cnblogs.com/tenyuan/p/16589854.html