承接前面第一章的笔记:
【计算机网络】八股文 | 第四章
本章内容:主要是TCP与UDP的相关知识
这里同样也推荐一些我觉得不错的博客,重点在于知识的share。
关于这里我比较推荐的是小林coding, 关于计算机网络小林博主的图解不得不说很nice,主要很直观。++
首先,对于TCP与UDP,我们需要先了解一下相关的概念
UDP(User Datagram Protocol,用户数据报协议)
一种无连接的、不可靠的、基于报文的全双工传输层协议。因为不需要建立连接所以 可以在网络上以任何可能的路径传输,因此能否到达目的地、到达目的地的时间以及内容的正确性都是不能被保证的。
【定义的扩展解释】
【特点】
TCP/IP(Transmission Control ProtocolInternet Protocol, 传输控制协议/网际协议)
指能够在多个不同网络间实现信息传输的协议簇 。
TCP/IP协议不仅仅指的是TCP 和IP两个协议,而是指一个由FTP、SMTP、TCP、UDP、IP 等协议构成的协议簇,只是因为在TCP/IP协议中TCP 协议和IP协议最具代表性,所以被称为TCP/IP 协议。
因特网地址是 TCP/IP 协议,比如 “xxx.xxx.xx.xxx” 就是一个 TCP/IP 协议。
TCP/IP是供已连接因特网的计算机进行通信的通信协议,定义了电子设备(比如计算机)如何连入因特网,以及数据如何在他们之间传输的标准。
TCP(Transmission Control Protocol,传输控制协议)
一种面向连接的、可靠的、基于字节流的全双工传输层协议。TCP 提供可靠的服务,也就是说,通过TCP连接传输的数据不会丢失,没有重复,并且按顺序到达。
图源于小林coding
TCP协议的特点:面向连接的、可靠的、基于字节流的全双工传输层协议
从前面的定义我们同样可以知道TCP和UDP的区别,这里汇总到表格上如下图所示:
下面总结来源于小林coding:
TCP应用场景: 效率要求相对低,但对准确性要求相对高的场景。因为传输中需要对数据确认、重发、排序等操作,相比之下效率没有UDP高。例如:文件传输(准确高要求高、但是速度可以相对慢)、接受邮件、远程登录。
UDP应用场景: 效率要求相对高,对准确性要求相对低的场景。例如:QQ聊天、在线视频、网络语音电话(即时通讯,速度要求高,但是出现偶尔断续不是太大问题,并且此处完全不可以使用重发机制)、广播通信(广播、多播)。
这里更多的是高频/常见的题目,不是知识讲解,所以关于TCP报文/UDP报文组成,区别之类的更多详细的知识,大家可以去【计算机网络】TCP/UDP篇这里阅读。
首先,非常重要,我们需要了解一下粘包的概念及相关知识,这里推荐大家先去阅读【TCP粘包是什么? 为什么UDP不粘包?为什么UDP要冗余长度字段?】这篇博客,作者小白debug讲得非常生动形象。
笔记链接:【TCP粘包是什么? 为什么UDP不粘包?为什么UDP要冗余长度字段?】
UDP不是流协议,有消息边界,不存在粘包的问题。要丢就是整个包都丢了。
首先,UDP是面向无连接的协议,它不像TCP协议那样需要建立连接,数据的传输也不保证可靠性。因此,在UDP协议下,不会出现TCP粘包的情况。
UDP协议在发送数据时,并不会像TCP协议那样对数据进行拆分和重组,它是以用户数据报的方式进行传输的。在发送端,数据被分成一个个用户数据报,每个用户数据报都包含一个标识符,接收端根据标识符来识别不同的数据包,从而避免了TCP粘包的问题。
同时,UDP协议也没有TCP协议那样的拥塞控制和流量控制等机制,数据传输的速度更快,因此也不容易出现TCP粘包的问题。
UDP在传输数据之前不需要先建立连接,远地主机的运输层在接收到UDP报文后,不需要确认,提供不可靠交付。总结就以下四点:
TCP 有三次握手机制还有 ARQ 协议等确保可靠性,但这导致 TCP 传输速度很慢,会有延迟,UDP 就不会有,在即时通信领域,这个延迟是不可接受的。
前面我们先提到了UDP没有粘包问题,所以类似的,TCP也经常会被文有粘包的问题应该怎么解决。
【什么是TCP粘包】
TCP粘包指的是在TCP协议下,由于发送端和接收端的不同步,或者是由于传输过程中拥塞等原因导致发送端发出的数据包,被接收端一次性接收到,并被视为一个整体,这就是TCP粘包。
TCP粘包的出现,是由于TCP协议的特性所导致的。TCP协议是面向连接的协议,它通过三次握手建立连接,保证数据传输的可靠性。而在数据传输过程中,发送端并不会把数据一次性全部发送出去,而是分成一个个数据包逐个发送,接收端也需要逐个接收。但是,由于TCP协议的流式传输特性,使得发送方和接收方并不能保证同步,发送方发送的多个数据包可能会被接收方视为一个数据包进行处理。
另外,由于网络中可能会存在拥塞、丢包等问题,导致数据的传输不稳定。如果发送方在短时间内连续发送多个数据包,接收方在处理这些数据包时就有可能将它们视为一个整体,从而出现TCP粘包的情况。
【解决TCP粘包问题的方法】
为了解决TCP粘包的问题,常用的方法有以下几种:
TCP粘包是在TCP协议下经常出现的问题,而UDP协议则没有这个问题。TCP粘包的原因是由于TCP协议的流式传输特性和数据传输不稳定所导致的。为了解决TCP粘包问题,可以采用定长包发送、特殊字符分隔和消息头添加长度信息等方法。在实际应用中,需要根据具体的情况选择合适的方法来解决TCP粘包的问题。
关于三次握手及四次挥手如果相关基础概念不是很了解可以看:一文搞懂TCP的三次握手和四次挥手
动图可看:两张动图-彻底明白TCP的三次握手与四次挥手
服务端新建套接字,绑定地址信息后开始监听,进入LISTEN监听状态。
客户端新建套接字绑定地址信息后调用connect,发送连接请求包SYN
,并进入请求发送SYN_SEN
T状态,等待服务器的确认。
服务端一旦监听到连接请求,就会将连接放入内核等待队列中,并向客户端发送请求包SYN和确认报文段ACK,进入请求已接收SYN_RECD
状态。
客户端收到SYN+ACK报文后向服务端发送确认报文段ACK,并进入连接已经建立成功ESTABLISHED
状态,开始读写数据。服务端一旦收到客户端的确认报文,就进入连接已经建立成功ESTABLISHED状态,就可以进行读写数据了。
套接字 (Socket) 是计算机系统中一种重要的接口,它用于在应用程序和网络协议之间进行通信。套接字通常由三个部分组成:本地套接字 (Local Socket)、远程套接字 (Remote Socket) 和协议套接字 (Protocol Socket)。
SYN_RECD 状态中的 "RECD" 表示 "Received" 的缩写,表示服务器已经接收到了客户端发送的 SYN 包,并且正在处理它。在 SYN_RECD 状态中,服务器正在检查客户端的请求是否符合服务器的选项,并且尚未发送 ACK 包给客户端。
在 TCP 连接中,ESTABLISHED 状态表示连接已经建立成功,客户端和服务器之间可以开始传输数据。在 ESTABLISHED 状态中,客户端和服务器之间的连接是稳定的,并且双方都已经确认对方的身份和协议。
主要原因:为了确认自己和对方的发送和接收功能都正常
阻⽌重复历史连接的初始化,造成连接,浪费资源。
举例:假设两次握手建立连接。那么当客户端第一次发送连接请求到服务端时,由于网络阻塞等原因,服务端暂时没有接收到请求。于是一段时间后,客户端再次发起第二次连接请求。这是服务端接收到请求,发出确认报文,建立连接。完成数据传输后,服务端再次接收到第一次未收到的连接请求,由于两次握手机制,会导致连接再次建立。
同步双方的初始序列号,确保可靠的同步。
TCP 协议的通信双⽅, 都必须维护⼀个「序列号」, 序列号是可靠传输的⼀个关键因素。
接收端可以去除重复数据。
接收端可以按照序列号顺序接收。
标识发送的数据包,哪些已经被收到。
两次握⼿只保证了⼀⽅的初始序列号能被对⽅成功接收,没办法保证双⽅的初始序列号都能被确认接收。
主要防止已经失效的连接请求报文突然又传送到了服务器,造成连接,浪费资源。
举例:假设两次握手建立连接。那么当客户端第一次发送连接请求到服务端时,由于网络阻塞等原因,服务端暂时没有接收到请求。于是一段时间后,客户端再次发起第二次连接请求。这是服务端接收到请求,发出确认报文,建立连接。完成数据传输后,服务端再次接收到第一次未收到的连接请求,由于两次握手机制,会导致连接再次建立。
第一次、第二次握手不可以携带数据,而第三次握手是可以携带数据的。假设第一次可以携带数据,如果有人恶意攻击服务器,每次都在第一次握手中的SYN报文放入大量数据,重复发送大量SYN报文,此时服务器会花费大量内存空间来缓冲这些报文,服务器就更容易被攻击了
握手失败的原因有两种,第一种是服务端没有收到SYN,则什么都不做;第二种是服务端回复了SYN+ACK后,长时间没有收到ACK响应,则超时后就会发送RST重置连接报文,释放资源
TCP还设有一个保活计时器,即心跳机制。
3次握手建立连接后,若长时间没有发送数据,则服务端会发送探测性的数据包,来确认连接是否仍然存在。
服务端没次收到客户端的请求,都会复原这个计时器。如果在2个小时内没有收到客户端的请求。服务端就会主动发送一个探测报文段,以后每隔75秒发送一次。若连续发送10个探测报文,客户端都没有反应,服务端就判定客户端故障,主动断开连接。
客户端主动调用close时,向服务端发送结束报文段FIN报,同时进入连接结束等待FIN_WAIT1状态;
服务器会收到结束报文段FIN报,服务器返回确认报文段ACK并进入关闭等待CLOSE_WAIT状态,此时如果服务端有数据要发送的话,客户端依然需要接收。(客户端只是关闭了发送)
客户端收到服务器对结束报文段的确认,就会进入到连接结束等待FIN_WAIT2状态,开始等待服务器的结束报文段;
(开始关闭服务端的发送) 服务器端数据发送完毕后,当服务器真正调用close关闭连接时,会向客户端发送结束报文段FIN包,此时服务器进入最终确认LAST_ACK状态,等待最后一个ACK的带来;
客户端收到服务器发来的结束报文段, 进入计时等待TIME_WAIT(通常是 1-2 分钟), 并发出送确认报文段ACK;
服务器收到了对结束报文段确认的ACK,进入CLOSED状态,断开连接。而客户端要等待2MSL的时间,才会进入到CLOSED状态。
其实在TCP握手的时候,接收端将SYN包和ACK确认包合并到一个包中发送的,所以减少了一次包的发送。
对于四次挥手,由于TCP是全双工通信,主动关闭方发送FIN请求不代表完全断开连接,只能表示主动关闭方不再发送数据了。
而接收方可能还要发送数据,就不能立即关闭服务器端到客户端的数据通道,所以就不能将服务端的FIN包和对客户端的ACK包合并发送, 只能先确认ACK,等服务器无需发送数据时在发送FIN包,所以四次挥手时需要四次数据包的交互
长连接和短连接的产生在于 Client 和 Server 采取的关闭策略,具体的应用场景采用具体的策略。
这里常见会有以下问题,这里直接放链接:
这里推荐阅读:
如果主动关闭方进入CLOSED状态后,被动关闭方发送FIN包后没有得到ACK确认,超时后就会重传一个FIN包。如果客户端没有TIME_WAIT状态而直接进入CLOSED状态释放资源,下次启动新的客户端就可能使用了与之前客户端相同的地址信息,有两个危害,第一种是这个刚启动的新的客户端绑定地址成功时,就会收到了一个重传的FIN包,对新连接就会造成影响。第二种是如果该新客户端向相同的服务端发送SYN连接请求,但是此时服务端处于LAST_ACK状态,要求收到的是ACK而不是SYN,因此就会发送RST重新建立请求。
MSL指的是报文在网络中最大生存时间。在客户端发送对服务端的FIN确认包ACK后,这个ACK包有可能到达不了,服务器端如果接收不到ACK包就会重新发送FIN包。所以客户端发送ACK后需要留出2MSL时间(ACK到达服务器器+服务器发送FIN重传包,一来一回)等待确认服务器端缺失收到了ACK包。也就是说客户端如果等待2MSL时间也没收到服务器端重传的FIN包,则就可以确认服务器已经收到客户端发送的ACK包
TIME_WAIT是主动关闭方出现的,一台主机出现大量的TIME_WAIT证明这台主机上发起大量的主动关闭连接。常见于一些爬虫服务器。这时候我们应该调整TIME_WAIT的等待时间,或者开启套接字地址重用选项
CLOSE_WAIT是被动关闭方收到FIN请求进行回复之后的状态,等待上层程序进一步处理,若出现大量CLOSE_WAIT,有可能是被动关闭方主机程序中忘了最后一步断开连接后调用close释放资源。这是一个 BUG.,只需要加上对应的 close 即可解决问题
由于TCP的下层网络(网络层)可能出现丢失、重复或失序的情况,TCP协议提供可靠数据传输服务。为保证数据传输的正确性,TCP会重传其认为已丢失(包括报文中的比特错误)的包。TCP使用两套独立的机制来完成重传,一是基于时间,二是基于确认信息。
TCP在发送一个数据之后,就开启一个定时器,若是在这个时间内没有收到发送数据的ACK确认报文,则对该报文进行重传,在达到一定次数还没有成功时放弃并发送一个复位信号。
TCP流量控制是为了控制发送方发送速率,保证接收方来得及接收。其中,TCP的流量控制机制是通过滑动窗口机制实现的。当接收端缓冲区满了,发送端就会停止发送数据,等待接收端发送ACK报文。当接收端缓冲区空了,发送端就会继续发送数据。
滑动窗口协议既保证了分组无差错、有序接收,也实现了流量控制。主要的方式就是接收方返回的 ACK 中会包含自己的接收窗口的大小,并且利用大小来控制发送方的数据发送。
滑动窗口协议的基本原理就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口;同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口。发送窗口和接收窗口的序号的上下界不一定要一样,甚至大小也可以不同。不同的滑动窗口协议窗口大小一般不同。发送方窗口内的序列号代表了那些已经被发送,但是还没有被确认的帧,或者是那些可以被发送的帧。
举例:
发送和接受方都会维护一个数据帧的序列,这个序列被称作窗口。发送方的窗口大小由接受方确定,目的在于控制发送速度,以免接受方的缓存不够大,而导致溢出,同时控制流量也可以避免网络拥塞。图中的4,5,6号数据帧已经被发送出去,但是未收到关联的ACK,7,8,9帧则是等待发送。可以看出发送端的窗口大小为6,这是由接受端告知的(事实上必须考虑拥塞窗口cwnd,这里暂且考虑cwnd>rwnd)。此时如果发送端收到4号ACK,则窗口的左边缘向右收缩,窗口的右边缘则向右扩展,此时窗口就向前“滑动了”,即数据帧10也可以被发送。
【背景】
如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。这一点和流量控制很像,但是出发点不同。流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。
【定义】
TCP拥塞控制是传输控制协议(英语:Transmission Control Protocol,缩写TCP)避免网络拥塞的算法,是互联网上主要的一个拥塞控制措施。它使用一套基于线增积减模式的多样化网络拥塞控制方法(包括慢启动和拥塞窗口等模式)来控制拥塞。在互联网上应用中有相当多的具体实现算法。
【面试推荐回答】
TCP的拥塞控制机制主要有四种算法:慢开始、拥塞避免、快重传和快恢复。慢开始是当主机开始发送数据时先探测网络,若一拥塞就慢下来,否则指数级增加;拥塞避免是当数据包被确认后,拥塞窗口线性增加;快重传是要求收到三个重复确认就重传;快恢复是要求收到三个重复确认后执行快恢复算法。
下面回答原笔记链接:面试题:详细讲一下拥塞控制?
拥塞控制是指在 TCP 网络中用于防止网络拥塞的一种技术,它通过降低发送端的发送速率以及限制传输的数据量来缓解网络拥塞。下面结合具体案例和技术,详细讲一下拥塞控制的工作原理和实现方法:
TCP 拥塞控制的基本流程如下:
TCP 实现拥塞控制的主要技术包括以下几种:
总之,拥塞控制是 TCP 网络中的一项重要技术,可以帮助有效地预防网络拥塞,保证网络传输的高效率和可靠性。TCP 拥塞控制的原理和实现方法非常多,以及如何度量拥塞的情况也需要考虑和纳入衡量标准之中。了解拥塞控制的策略和方法可以帮助网络的工程师更好地进行网络设计和维护。
TCP通信中,若两端长时间没有数据往来,则这时候每隔一段时间,服务端会向客户端发送一个保活探测数据报,要求客户端进行回复。若连续多次没有收到响应,就认为连接已经断开。长时间默认为7200s,每隔一段时间默认为75s,连续多次无响应默认为9次。这些数据都可以在套接字中修改,接口:Setsockopt
ISN不是固定的而是动态生成的,三次握手的其中一个重要功能是客户端和服务端交换 ISN,以便让对方知道接下来接收数据的时候如何按序列号组装数据。如果 ISN 是固定的,攻击者很容易猜出后续的确认号
【了解】
SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。
【定义】
SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。
【为什么服务器容易受到SYN攻击】
服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪泛攻击。
【如何检测呢】
检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。
【如何防御】
常见方法:(1)缩短超时(SYN Timeout)时间(2) 增加最大半连接数(3)过滤网关防护(4) SYN cookies技术
下一章笔记的链接:
【计算机网络】八股文 | 第六章
笔记链接:待更新
主要知识点:待更新