前言
网络协议是每个开发人员都应该掌握的知识,TCP 和 UDP是TCP/IP 中有两个具有代表性的传输层协议,本文将介绍两者的基本概念以及区别。
一、TCP/IP网络模型
计算机与网络设备要相互通信,双方就必须基于相同的方法,所有的一切都需要规则,我们将这种规则称为协议。
TCP/IP不是指这两个协议的合称,而是指因特网整个TCP/IP协议簇。比如:TCP,UDP,IP,FTP,HTTP,ICMP,SMTP 等都属于 TCP/IP 簇内的协议。
从协议分层模型方面来讲,TCP/IP由4个层次组成:网络接口层、网络层、传输层和应用层。
二、UDP
UDP:用户数据报协议(User Datagram Protocol)。在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。
UDP协议是一个面向无连接的协议,传输数据时,不需要建立连接,不管对方端服务是否启动,直接将数据、数据源和目的地都封装在数据包中,直接发送。
UDP的特点
1. 面向无连接:不需要建立连接,不管对方端服务是否启动,想发数据就可以开始发送。
2. 支持一对多,多对多,多对一的方式,也就是说 UDP 提供了单播,多播,广播的功能。
3.不可靠性:不可靠性体现在无连接上,通信都不需要建立连接,这样的情况肯定不可靠
4. UDP 的头部开销小,只有八字节,相比 TCP 的至少二十字节要少得多,传输数据报文高效。
应用场景:用于传输可靠性要求不高、数据量大的数据,例如抖音等视频服务就使用了UDP
三、TCP
TCP:传输控制协议 (Transmission Control Protocol)。TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠的数据传输。
TCP的特点
1.面向连接:发送数据之前必须在两端建立连接(三次握手)
2.可靠性高:校验和、确认应答+序列号、超时重传、流量控制、拥塞控制等方式保证可靠性。
3.仅支持单播传输
4.TCP提供全双工通信,数据能在两个方向上独立进行传输。
应用场景:用于传输对可靠性要求高、数据量要求小的数据,比如支付宝转账用的就是TCP。
3.1三次握手
TCP数据在传输之前首先需要建立连接,建立连接需要进行三次通信,一般称为三次握手。
- 客户端发送SYN(seq=x)报文给服务器,表示请求连接,进入SYN-SENT(同步已发送)状态,等待服务器确认。
- 服务器收到SYN报文,回应一个SYN(seq=y),ACK(ack=x+1)的报文,表示确认可以连接,进入SYN-RCV(同步已接收)状态。
- 客户端收到服务器端的SYN报文,回应一个ACK(ack=y+1)报文,进入Established(连接已建立)状态。
- 三次握手完成后,TCP客户端和服务器端成功建立连接,可以开始传输流程。
注意:SYN,ACK,FIN为标记位,分别表示:请求连接,确认,断开连接。ack(确认号)的值为上一次收到报文中的seq(序列号)值+1,就是表明对上一次请求的确认,告诉对方我已经收到你的请求了。
现在用通俗的例子来理解三次握手的过程:
有一个男生(客户端)喜欢一个女生(服务器端),
1.男生给女生发短信请求女生做他的女朋友(这里就是第一次握手,客户端请求连接)
2.女生收到后回复短信表示同意男生的请求(第二次握手,服务器端表示可以连接)
3.男生收到短信后回复确认收到(第三次握手,客户端和服务器端都知道了对方的意愿),这时三次握手完成,客户端和服务器端可以互相传输数据。
3.2四次挥手
在数据传输完成后断开连接的时候要进行4次通信,一般被称为四次挥手。
- 客户端调用断开连接的请求,向服务器端发送一个终止标志位FIN=1,seq=u的消息,表示客户端关闭链路前要发送的数据已经发送完毕。此时客户端处于FIN-WAIT-1状态。
- 服务器收到这个FIN消息后返回一个ACK=1,ack=u+1,seq=v的消息给客户端,表示接收到客户端断开链路的操作请求,这时TCP服务器端通知高层应用进程释放客户端到服务器端的链路,服务器处于CLOSE-WAIT状态,即半关闭状态。客户端收到消息后处于FIN-WAIT-2状态。
- 服务器关闭链路前将需要消息发送给客户端,数据发送后,发送一个终止标志位FIN=1,ACK=1,seq=w,ack=u+1的消息给客户端,表示关闭链路前需要发送的消息已经发送完毕,请求客户端确认关闭,此时服务器处于LAST-ACK状态。
- 客户端收到这个最终FIN消息后,发送一个ACK=1,seq=u+1,ack=w+1的消息给服务器,表示准备断开链路。此时客户端处于TIME-WAIT状态,经过等待计时器2MSL(最长报文段寿命)设置的时间后,客户端进入CLOSE状态。
同样用一个通俗的例子来理解四次握手的过程:
有一个男生(客户端)要和一个女生(服务器)分手:
1.男生给女生发短信请求分手(第一次握手,客户端请求断开连接)
2.女生收到后回复我已收到(第二次挥手,服务器已经知道客户端要断开的意愿)
3.之后女生这边把恩怨情仇都处理完发给男生并且问你确定要断开吗(第三次挥手,服务器端已经都处理完问题了,表示可以断开了)
4.男生回复我确定要断开(第四次挥手,客户端确定断开连接)。
TCP断开连接为什么比建立连接多一个步骤呢?其实很简单,因为谈恋爱的时候还没有矛盾纠葛,但是分手的时候有矛盾需要处理!
四、三次握手和四次挥手的常见问题
为什么不是二次握手?
防止已失效的连接请求又传送到服务器端,因而产生错误。
如果仅仅只有两次握手,如果客户端已经连接超时失败,放弃连接了。这个时候超时的信号又到了服务端,服务第二次握手,认为建立了连接,服务器资源就被浪费了。如果是三次握手,就不存在这个问题了。因为客户端已经放弃了,服务端是不会收到第三次握手的,不会误认为连接建立成功。
为什么不是四次握手?
本质上三次握手已经可以建立可靠的连接,如果四次,那么就造成了资源上的浪费,只需要三次握手,可以提高连接的速度与效率。
为什么客户端在TIME-WAIT装填必须等待2MSL时间呢?
- 第一,为了保证客户端发送的最后一个ACK报文段能够到达服务端。客户端发送的ACK报文段可能丢失,因而使服务器收不到对自己已发送的释放连接报文段的确认,使服务器无法关闭,造成服务器资源的浪费。而服务器会重传连接释放报文段,客户端就能在2MSL时间内收到这个重传释放报文段,然后重传一次确认,重新启动2MSL计时器。最终,客户端和服务器端都能进入CLOSE状态。
- 客户端在发送完最后一个ACK报文段后,再经过时间2MSL。就可以使本连接持续的时间内所产生的所有报文段都在网络中消失。这样就可以在下一个新的连接中不会出现这种旧的连接请求报文段。
现在我们再来思考一下一个问题,如果已经建立了连接,客户端突然出现故障了怎么办?
答案:使用保活计时器。
- TCP服务器进程每收到一次TCP客户进程的数据,就重新设置并启动保活计时器(2小时定时)。
- 若保活计时器定时周期内未收到TCP客户进程发来的数据,则当保活计时器到时后,TCP服务器进程就向TCP客户进程发送一个探测报文段,以后则每隔75秒钟发送一次。若一连发送10测报文段后仍无TCP客户进程的响应,TCP服务器进程就认为TCP客户进程所在主机出了故障,接着就关闭这个连接。
五、UDP和TCP的区别
下面从是否连接,可靠程度以及适用场景等角度对比UDP和TCP的区别
总结
TCP提供了面向连接的可靠服务,适合于安全性要求较高的数据,例如转账。UDP提供了面向无连接不可靠的服务,虽然没有TCP可靠,但在实时性要求较高的场景有很大作为,例如视频聊天。TCP握手和挥手的本质:让我知道你已经知道了,保证TCP的可靠性。关于为什么TCP是四次挥手的问题读者可以自行查阅相关资料了解。