TCP/UDP的区别
TCP是一个面向连接,可靠的,流式服传输协议
UDO是一个无连接,不可靠的,数据报传输协议
1.连接
TCP通过三次握手,四次挥手建立连接
UDP无连接
2.可靠性
TCP通过数据校验,ACK确认,超时重传建立可靠的连接
UDP会乱序,丢包等
3.头部开销
TCP头部开销至少20字节
UDP头部开销固定8字节
4.传输顺序
TCP通过序列号保证数据包有序到达
UDP不维护数据传输顺序,传输顺序不固定
5.传输速度
TCP因连接管理,流量控制,拥塞控制等传输延迟较高。
UDP无控制开销,因此它的传输速度较快,适合实时应用。
6.流量控制
TCP通过滑动窗口动态调整发送速率,避免接收缓冲区溢出
UDP无流量控制,可能会丢包
7.拥塞控制
TCP通过慢启动,拥塞避免,快重传等算法避免网络堵塞
UDP无拥塞控制,可能加剧阻塞。
8.应用场景
TCP应用于HTTP/HTTPS,FTP
UDO应用于DNS 视频会议 在线游戏
UDP怎么实现其可靠传输
UDP本身是无连接的传输层协议,不能保证数据的可靠传输,但是可以在应用层的设计来模拟TCP的可靠机制。
1.提供确认序列号:为每个数据包附加一个唯一的序列号,接收端反馈ACK确认,确保有序与完整
2.提供超时重传:未收到ACK时重传数据,动态计算RTO(重传的网络时间),适应网络波动。
3.滑动窗口机制:允许连续发送多个数据包,通过累计ACK减少通信次数。
TCP三次握手四次挥手流程
三次握手
第一次握手:客户端发送SYN报文表示请求建立连接,并附带序列号seq=i,客户端进入SYN_SEND状态。
第一次握手丢失:如果客户端发送SYN报文后,迟迟没有收到ACK+SYN报文,触发超时重传机制,客户端重发SYN报文
第二次握手:服务器收到客户端发来的SYN报文后,接受其序列号,并恢复SYN+ACK报文,序列号为j,ack为i+1,服务器进入SYN_RECV状态
第二次握手丢失:如果服务器发送SYN+ACK报文后,客户端迟迟没有收到ACK报文,触发超时重传机制,客户端重发SYN报文
第三次握手:客户端收到服务器发来的SYN_ACK报文后,验证其序列号,并返回一个ACK=j+1的报文,正式建立成功。
第三次握手丢失:如果客户端接受SYN+ACK报文后,服务器迟迟没有收到ACK报文,触发超时重传机制,重发SYN+ACK报文
为什么是三次握手不是两次or四次?
1.三次握手才可以阻止重复的报文连接
三次握手才可以同步双方的序列号
三次握手才可以避免资源浪费
两次握手:无法阻止历史连接的建立,会造成双方资源浪费,也无法可靠的同步双方序列号。
四次握手:三次握手已经是理论上最少的次数,所以不需要使用更多的通信。
四次挥手
第一次挥手:主动关闭的一方发送FIN报文随带序列号seq=i,表示自己要关闭连接了。主动关闭的一方进入FIN_WAIT1状态.
第一次挥手丢失:当主动方发送FIN报文后迟迟没有收到ack报文就会超时重传FIN报文
第二次挥手:被动方接受到FIN报文后,回复ACK报文,ack=i+1,被动方进入close_wait状态。主动方收到后进入FIN_WAIT2.
第二次挥手丢失:当被动方收到FIIN报文后,发送ACK报文,ACK报文丢失,主动方迟迟收不到ACK报文,主动方超时重传FIN报文。
第三次挥手:当被动方表示自己没有信息发送后,发送FIN报,附带序列号seq=j,随后进入Last_ACK状态。
第三次挥手丢失:当被动方发送FIN报文后迟迟没有收到ack报文就会超时重传FIN报文
第四次挥手:主动方收到FIN报文后,发送ACK报文,ack=j+1,随后进入time_wait状态,被动方收到后进入close状态。
第四次挥手丢失:当主动方收到FIIN报文后,发送ACK报文,ACK报文丢失,被动方迟迟收不到ACK报文,被动方超时重传FIN报文。
为什么挥手需要四次
因为TCP协议是全双工通信,一方关闭连接时,仅表示这一方不再发送数据但是可以接受数据,并不能保证另一方不发送数据。
挥手可以为三次:前提是确保双方没有数据可以发送。
TIME_WAIT状态
只有主动关闭的一方才存在TIME_WAIT状态,是为了保证在第四次挥手丢失的情况下,主动关闭的一方还有接受能力去接受被动方发送来的FIN报文,并回复ACK报文。
1.防止历史连接的数据被下一个相同的四元组的连接错误接受。
保证被动方可以正确被关闭
TCP的keep-alive和HTTP的keep-alive
HTTP的keep-alive
他是HTTP长连接的标识,是浏览器能在一个TCP连接中发送多个请求与响应,避免多次建立和关闭连接的开销。
通过请求头中的字段connection:keep-alive来实现,并且是在**应用层(用户态)**实现的。
TCP的keep-alive
他是**TCP(内核态)**的保活机制,用于在TCP连接上检测空闲时的连接状态机制
TCP建立连接后,如果一段时间有没有数据传输,该机制内核态的TCP协议栈就会发送探测包测试连接状态是否还存在。
如果对端程序正常工作,TCP保活的探测报文发送给对端,对端正常访问,这样的TCP保活时间会被重置,等待下一个TCP保活时间的到来。
如果对端主机宕机,探测报文没有响应,到达保活探测次数后,TCP会报告该TCP连接已经死亡。

注意:应用程序若想使用TCP保活机制,需要通过socket接口设置SO?_KEEPALIE选项才能够生效。