TCP
TCP
TCP和UDP工作在传输层,是用来对数据进行传输和通信
TCP和UDP有什么特点和区别?
TCP的主要特点:
面向连接 :TCP协议会将通信双方建立起连接
- 如何做链接管理的?通过TCP三次握手来建立连接、通过TCP四次挥手来断开连接
- 重传机制有哪些?
- 超时重传:发送数据时设定一个定时器,当超过指定的时间后,没有收到对方的ACK确认应答报文,就会重新发该数据。超时周期是动态变化的,会出现超时周期相对较长的情况。于是就出现了快速重传。
- 快速重传:当发送方收到三个相同的ACK报文时,会在定时器过期之前,重传丢失及丢失之后的所有数据包。会出现重传没有收到的数据还是重传没有收到数据之后的所有数据?
- SACK(选择确认性):在TCP的头部选项里添加一个SACK,让发送方知道哪些数据没有被成功收到,可以只重传没有收到的数据
- D-SACK:优化了SACK
- 可以让发送方知道是发送的包丢失了,还是接收方返回的ACK包丢失了
- 可以知道是不是发送方发送的包是不是被网络延迟了
- 可以知道网络中是不是把发送方的数据包给复制了
可靠的:TCP是一种可靠的传输协议,通过使用确认和重传机制来确保数据可靠性
面向字节流
怎么保证数据的有序性?给每个数据编上序列号,并且发送总数据长度及每个数据的长度,从而来确定数据是否有序,有便于传输后的确认及丢失后重传不会出现乱序。
粘包问题
粘包问题指服务端接收多个数据包时,无法区分这些数据包的边界,导致解析错误。
解决方法:一般通过固定消息的长度、用特殊字符作为边界、使用自定义消息结构三种方式来进行分包
所以TCP主要用于上传下载、HTTP请求、文件传输等场景
UDP的主要特点:
- 无连接
- 不可靠
- 面向报文
UDP相比于TCP的传输速度更快,但不保证传输的结果(不关心传送的消息是否成功被接收),所以它主要用于音频/视频的通话、实时游戏等场景。
实现一个可靠的UDP: 可以在UDP的底层实现一些TCP的机制,例如基于UDP的QUIC协议可以实现类似TCP的可靠性传输。
TCP 的三次握手
- 第一步:客户端发送SYN(包)给服务端。这个包包含了客户端的初始序列号以及请求建立连接的标志位(SYN=1)
客户端:SYN_SENT(同步已发送状态)、服务端:LISTEN(监听状态)
- 第二步:服务端接收到SYN包后,会发送一个SYN/ACK(同步/确认)包给客户端。这个包包含了服务器的初始序列号以及对客户端的请求建立连接的确认。
客户端:SYN_SENT(同步已发送状态)、服务端:SYN_RCVD(同步已接收状态)
- 第三步:客户端收到SYN/ACK包后,会发送一个ACK(确认)包给服务器,确认服务器的请求建立连接。此时连接已经建立,客户端和服务器可以开始进行数据传输。
客户端:ESTABLISHED(已建立连接状态)、服务端:ESTABLISHED(已建立连接状态)
通过三次握手,客户端和服务器就建立了可靠的连接。这种机制可以确保双方都同意建立连接,并且可以互相确认对方的请求和确认。
关于 TCP 的三次握手相关
- 为什么TCP是三次握手,而不是两次或四次?
反证法:两次太少,不能保证可靠的连接,并且可能造成SYN超时问题、四次太多,会造成资源浪费。
- 第三次握手时,发送方可以带其他数据吗?
可以带其他数据但是根据TCP协议的规定,第三次握手时不会携带其他数据。第三次握手知识用于确认连接的建立,并不包含其他应用层数据。
TCP 的四次挥手
第一步:当客户端想要关闭连接时,它发送一个FIN(结束)包给服务器,表示不再发送数据给服务端了。
客户端:FIN_WAIT_1(终止等待状态1)、服务端:CLOSE_WAIT(关闭等待状态)
第二步:服务端收到FIN包后,发送一个ACK包给客户端,确认收到了客户端的关闭请求,但是可能还有一些数据没有处理完
客户端:FIN_WAIT_2(终止等待状态2)、服务端:LAST_ACK(最后确认状态)
第三步:服务器发送一个FIN包给客户端,表示服务器也准备关闭连接
客户端:TIME_WAIT(时间等待状态)、服务端:CLOSED(关闭状态)
第四步:客户端收到FIN包后,发送一个ACK包给服务器,确认收到了服务器的关闭请求,此时连接关闭
关闭连接后是立马断开的吗?
不是。在四次挥手完成后,连接会进入TIME_WAIT状态,这个状态会持续一段时间(通常是2倍的MSL,即最大报文寿命),用来确保在网络中所有的数据包都已经被正常接收。在TIME_WAIT状态结束后,连接才会完全关闭,资源被释放。
为什么需要四次挥手?讲讲time_wait和close_wait。
TCP连接是双向传输数据的,当有一方需要断开连接时,会发送一个FIN包,对方回复一个ACK包,一个方向上的连接关闭了,双向就需要两个FIN-ACK包才能完成断开连接操作,故需要四次挥手操作。
time_wait: 表示一个连接已经完成了关闭状态,并且在等待最后的确认报文。
主要有两个作用:
防止上一次连接中的延迟或重复的数据包被下一次复用连接错误 的接收
确保被动关闭方能在规定时间内正常关闭连接
如果没有time_wait状态或者time_wait的时间太短,就可能导致数据错乱或者连接失败
close_wait: 表示对方已经发送了关闭连接的请求,等待本端应用程序也关闭连接。
主要作用:
- 为了让应用程序有机会处理完剩余的数据,并主动关闭连接。
如果没有应用程序没有及时调用close()操作,就可能导致大量的close_wait主状态积累,占用系统资源
- 0
- 0
- 0
- 0
- 0
- 0