TCP相关知识
TCP相关知识
tcp简介 :面向字节流 可靠的 面相连接的协议
面向连接:意味着交换数据之前,需要建立完整的TCP连接,
基于字节流:交换的数据格式是字节(byte)构成有序,但是无结构的 字节流,连接正常建立完成,客户端发送无特殊格式的字节流,存在缓冲结构用于接收数据。
TCP报文结构:
端口号:
序号
确认序号
首部长度
保留字段
控制位
窗口大小
校验和
紧急指针
选项
有效数据部分
可靠性:确保可靠性依靠如下手段
合理的数据大小:
校验和
序号和确认序号
超时重传
连接管理:三次握手,四次挥手
流量控制
拥塞控制
TCP 和 UDP 的区别
具体区别:
UDPTCP是否连接无连接面向连接是否可靠不可靠,没有确认机制、流量控制和拥塞控制可靠,有确认机制、流量控制和拥塞控制连接对象个数支持一对一,一对多,多对一和多对多交互通信只支持一对一通信传输方式面向报文面向字节流首部开销首部开销小,固定8字节首部开销较大,最小20字节,最大60字节适用场景适用于实时应用(IP电话、视频会议、直播等)适用于要求可靠传输的应用,如文件传输等
TCP的连接控制:
建立连接
三次握手:
第一次握手:客户端发送SYN=1 标识建立连接,并初始化seq,发送完成客户端进入 SYN-SENT状态,等待服务端确认
第二次握手:序号 seq 设置为服务器初始序号y。发送完报文段2后,服务器进入 SYN-RECEIVED 状态
第三次握手:客户端在收到报文段2后,向服务器发送报文段3,其 ACK 标志位为1,代表对服务器做出应答,确认序号字段 ack 为 y + 1,序号字段 seq 为 x + 1。此报文段发送完毕后,双方都进入 ESTABLISHED 状态,表示连接已建立。
常见面试题 1: TCP 建立连接为什么要三次握手而不是两次?
A1:
TCP 实现了可靠的数据传输,原因之一就是 TCP 报文段中维护了序号字段和确认序号字段,如果是两次握手,只有发起方的初始序号可以得到确认,而另一方的初始序号则得不到确认。
三次握手才能让双方均确认自己和对方的发送和接收能力都正常
防止已过期的连接请求报文突然又传送到服务器,因而产生错误
常见面试题2: TCP 建立连接为什么要三次握手而不是四次?
A2:相比上个问题而言,这个问题就简单多了。因为三次握手已经可以确认双方的发送接收能力正常,双方都知道彼此已经准备好,而且也可以完成对双方初始序号值得确认,也就无需再第四次握手了。
常见面试题3: 有一种网络攻击是利用了 TCP 建立连接机制的漏洞,你了解吗?这个问题怎么解决?
A3:在三次握手过程中,服务器在收到了客户端的 SYN 报文段后,会分配并初始化连接变量和缓存,并向客户端发送 SYN + ACK 报文段,攻击者发送大量的 SYN 报文段到服务器请求建立连接,但是却不进行第三次握手,这会导致服务器打开大量的半开连接,消耗大量的资源,最终无法进行正常的服务。
四次挥手:
客户端发送关闭连接的报文段,FIN 标志位1,请求关闭连接,并停止发送数据。序号字段 seq = x (等于之前发送的所有数据的最后一个字节的序号加一),然后客户端会进入 FIN-WAIT-1 状态,等待来自服务器的确认报文。
服务器收到 FIN 报文后,发回确认报文,ACK = 1, ack = x + 1,并带上自己的序号 seq = y,然后服务器就进入 CLOSE-WAIT 状态。服务器还会通知上层的应用程序对方已经释放连接,此时 TCP 处于半关闭状态,也就是说客户端已经没有数据要发送了,但是服务器还可以发送数据,客户端也还能够接收。
客户端收到服务器的 ACK 报文段后随即进入 FIN-WAIT-2 状态,此时还能收到来自服务器的数据,直到收到 FIN 报文段。
服务器发送完所有数据后,会向客户端发送 FIN 报文段,各字段值如图所示,随后服务器进入 LAST-ACK 状态,等待来自客户端的确认报文段。
客户端收到来自服务器的 FIN 报文段后,向服务器发送 ACK 报文,随后进入 TIME-WAIT 状态,等待 2MSL(2 * Maximum Segment Lifetime,两倍的报文段最大存活时间) ,这是任何报文段在被丢弃前能在网络中存在的最长时间,常用值有30秒、1分钟和2分钟。如无特殊情况,客户端会进入 CLOSED 状态。
服务器在接收到客户端的 ACK 报文后会随即进入 CLOSED 状态,由于没有等待时间,一般而言,服务器比客户端更早进入 CLOSED 状态。
常见面试题1: 为什么 TCP 关闭连接为什么要四次而不是三次?
A1:在数据发送完后,服务器会向客户单发送 FIN 报文,表示数据已经发送完毕,请求关闭连接,然后客户端再做出应答,因此一共需要四次挥手。
常见面试题2: 客户端为什么需要在 TIME-WAIT 状态等待 2MSL 时间才能进入 CLOSED 状态?
A2:客户端为了确保服务器收到了 ACK,会设置一个定时器,并在 TIME-WAIT 状态等待 2MSL 的时间,如果在此期间又收到了来自服务器的 FIN 报文段,那么客户端会重新设置计时器并再次等待 2MSL 的时间,如果在这段时间内没有收到来自服务器的 FIN 报文,那就说明服务器已经成功收到了 ACK 报文,此时客户端就可以进入 CLOSED 状态了。
TCP 的流量控制与滑动窗口
什么是 流量控制 ?
TCP 连接双方的主机都为该连接设置了发送缓存和接收缓存,这些缓存起到了蓄水池的作用
滑动窗口
发送缓存中的字节分类
第一类:已发送且已确认,这些数据已经发送成功并已经被确认的数据,比如图中的前31个bytes,这些数据其实的位置是在窗口之外了,下一步将被移出发送缓存。窗口内顺序最低的字节被确认之后,窗口左边界会向右移动,称为窗口合拢。
第二类:已发送但未收到确认,这部分数据已经被发送出去,但是还没有收到接收端的 ACK,认为并没有完成发送,这部分数据属于窗口内的数据。
第三类:未发送但是接收方已经准备好接收,这部分是尽快发送的数据,这部分数据已经被加载到缓存中,也在发送窗口中,正在等待发送,其实这个窗口是完全有接收方告知的,接收方告知当前可以接受这些数据,所以发送方需要尽快的发送。
第四类:未发送且接收方未准备好接收,这些数据属于未发送,同时接收端也不允许发送的,因为这些数据已经超出了发送端所接收的范围。