TCP/UDP详解
TCP
三次握手
tcp报文结构:
第一次握手:客户端发送tcp数据包标志位SYN设置为1,随机产生顺序号seq number = X的数据包到服务器,并进入SYN_SENT状态,服务器由SYN为1知道A要求建立连接
第二次握手:服务器收到请求后要确认联机信息,向客户端发送tcp数据包,标志位ACK设置为1,SYN为1,确认号ack number=主机的顺序号seq + 1 = X + 1,随机产生seq为y的包,此时服务器进入SYN_RCVD状态
第三次握手:客户端收到tcp数据包,检查ack number是否正确,若正确客户端回再发送标志位ACK位1,ack number = 服务器的seq + 1 = y + 1的数据包,服务端检查ACK为1则连接建立成功,Client和Server进入ESTAB-LISHED状态完成三次握手,可以传输数据。
四次挥手
- 第一次:Client发送请求断开连接数据包,发送一个FIN包,关闭Client到Server的数据传送。ClientFIN_WAIT_1状态。
- 第二次:Server接受到数据包后,发送应答包,返回一个ACK包确认Client断开,然后Server进入CLOSE_WAIT状态,Client收到应答后转到FIN_WAIT_2状态。
- 第三次:Server发送完毕数据后 发送一个断开连接数据包FIN,告诉Client我这也准备关了
- 第四次:client收到后变为TIME_WAIT状态,然后发送一个应答包ACK给server,server进入close状态,完成四次挥手。
图片来自:https://www.cnblogs.com/zhuzhenwei918/p/7465467.html
TCP为什么是三次握手四次挥手
科普一下全双工
全双工:允许数据在两个方向上同时传输(A->B且B->A)
单工:只允许A->B或者B->A
半双工:一段时间内只有一个动作发生如A->B,那么下一个B->A得等到A->传输停止。
为什么是三次握手?
因为信道不可靠,可能存在延时或者丢包,三次是满足可靠传输的最小次数。
假设两次握手,例如C向S发起tcp请求,S收到了请求后向C返回确认,此时S已经完成了连接认为可以发送数据了,然而C还没有收到确认包,S开始向C发送数据,C认为还没有建立连接就会忽略掉所有数据包,S端迟迟没有收到确认包又会重复发送分组包,形成死循环。
那么为什么不是四次握手?
三次已经建立了稳定的连接关系,四次的话会延长连接的时间,出现网络问题时会大大延长连接时间。
为什么是四次挥手?
因为tcp是全双工传输的并且信道可能不可靠,当client端发送完数据后发送FIN包表示关闭连接,而Server端可能还没发送完毕或者存在延迟,直接关闭容易出现错误
所以四次挥手在client端发送FIN包后仅仅是Client表示我发送完了但是没断开连接,Server回复ACK表示我收到了,此时若Server还有数据没发送,则等到发送完再向Client发送FIN包表示我也发完了可以断开连接,最后Client回复ACK包表示好的我收到了,TCP连接断开。
为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
假定网络状态不好,返回给Server的ACK包没有被送达,那么Server将会反复给Client发送FIN包,2MSL是报文发送和回复所需的最大时间,在2MSL内又收到FIN包则表示Server没有收到ACK,那么Client将会再次发送,若超过2MSL时间没有收到FIN则表示对方已经收到ACK包,进入close。
TCP和UDP的区别
- TCP是面向连接的,传输之前要三次握手成功才会传输,UDP则是无连接的。
- TCP可以保证可靠传输(有连接、超时重传、应答机制),UDP不能保证可靠传输一定送到。
- TCP是基于流模式(tcp把数据包看成一连串无边界的字节流,一段段传输构成整个数据块),UDP是基于数据报(每一个数据报都是一个独立的对象,有指定的大小)
- TCP只能点到点,而UDP可以是一对一,广播,多播。
TCP/UDP的使用场景
- TCP主要用于实现可靠传输的情况,例如文件传输,发送和接收邮件等
- UDP用于高速传输和实时性较高的场合,例如QQ电话,视频聊天,直播出现丢包也只是短暂的卡顿。
使用TCP/UDP的协议有哪些?
①TCP :FTP,Telnet(远程登录),SMTP,POP3(和SMTP对应用于接收邮件),HTTP
②UDP对应协议:DNS,SNMP(简单网络管理协议),TFTP(简单文件传输协议,使用了编号确认发送的包是否有丢失)
TCP是如何保障可靠传输的?
建立连接时的三次握手,断开连接时的四次挥手,传输数据时有超时重传,滑动窗口,和流量控制,拥塞控制机制保证可靠传输。
- 超时重传ARQ:
发送方A
持有超时计时器,当超时计时器到期时还没有收到接收方B
返回的确认报文则会重新发送一份数据。
那么就有可能有两种情况:
- B没有收到A发送的数据,那么超时重传后A会保留发送的数据副本,直到收到B的确认报文才会清除
- A丢失了B返回的确认报文,超时重传后B再次收到重复编号的数据,则会直接丢失这个重复数据然后给A返回确认报文。
在TCP协议中使用的是连续ARQ协议,因为单个分组的发送效率太低,使用连续ARQ协议一次发送多个分组,和滑动窗口配合使用。
- 滑动窗口协议:
滑动窗口协议在发送方和接收方各维护了一个滑动窗口,发送方是发送窗口,接收方是接受窗口。
发送方
:可以一次性发送窗口中所有的分组数据,并等待接收方的回应,按照确认分组的位置向右滑动窗口。接收方
:采用累计确认的模式,也就是说接收方可以不用对每一个分组去返回确认,而是收到多个分组后按照次序对最后的一个分组数据返回确认,也就是该分组及该分组之前的分组已经全部收到。例如分组12345,五组数据,接收方收到了1 2 4 5中间缺了个3,那么接收方返回的是分组2的确认,发送方则会重新发送后三组数据。
图片来自:https://www.cnblogs.com/blythe/articles/7348812.html
- 流量控制
- 问题起因:
TCP连接的双方都有固定大小的缓冲空间,当接收端的缓冲区满了以后发送端继续发送则会造成丢包。
通俗的说就是控制发送速度让接收端来得及处理接收。 - 流量控制的原理:在TCP报头信息中有一个字段叫
窗口大小
,窗口大小的内容实际上是接收端接收数据缓冲区的剩余大小
。接收端会在确认应答发送ACK报文时,将自己的窗口大小填入,发送端会根据ACK中的窗口大小值而改变自己的发送速度。当窗口大小为0时发送端停止发送,并启动一个计时器,周期的发送零窗口探测报文段
,当接收端返回的窗口大小大于0时则继续发送
- 拥塞控制
- 问题起因:计算机网络中的带宽、交换结点中的缓存和处理机等,都是网络的资源。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就会变坏。这种情况就叫做拥塞。
- 拥塞控制解决方式:
慢启动、拥塞避免、快重传、快恢复
首先科普一下:发送方维持一个叫拥塞窗口cwnd的状态变量,该变量的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等同于拥塞窗口,另外考虑到流量控制机制,接收方的接收能力有限,发送窗口实际可能小于拥塞窗口。
- 慢启动:在开始发送数据时,不一开始就发送大量数据,而是设置拥塞窗口为1发送极少量探测一下网络的拥塞程度,然后指数的增长拥塞窗口(cwnd)的值,当达到一个阈值(ssthresh)时开始执行
拥塞避免算法
。 - 拥塞避免:进入拥塞避免后,cwnd的增长速度放慢,每次+1而不是指数加倍了。
- 补充:无论是慢开始还是拥塞避免阶段,只要发送方检测到了网络拥塞(没有收到确认),就把ssthresh值设置为出现拥塞时的
发送窗口的一半
,然后将拥塞窗口大小设置为1,执行慢开始算法,这样可以迅速减少主机发送到网络中的分组数,使发生拥塞的节点有足够时间处理堆积的分组。
- 快重传
起因:一条TCP连接可能会因为等待重传计时器超时
(发送了分组数据,等待回应确认应答ACK的最长时间,超过就会重传)而空闲较长的时间。
解决:快重传要求接收方在收到一个失序报文后就立即发出重复确认,如下图,当M3丢失后发送方收到M4,M5,M6都是失序的报文段,因为中间缺少了M3,那么快速重传要求立刻返回M2的确认(不理解可以回顾滑动窗口),那么发送端在收到三个重复的确认ACK时则判断出分组出现了丢失,立即重新传输报文段,而不必等待重传计时器超时后发送。
- 快恢复
当发送方连续收到三个重复确认时,就执行乘法减小算法,将ssthresh阈值减半,然后执行拥塞避免算法(因为能收到好几个重复的确认一般不是出现拥塞,所以没有执行慢开始算法)