一.概念
1)UDP和TCP的特点和区别
UDP:无连接,尽最大可能交付,面向报文,支持一对一、一对多、多对多的通信。
TCP:面向连接,可靠交付,有流控,拥塞控制,全双工通信,面向字节流,一对一(点对点)。
流的概念:传输双方的一种连接逻辑,数据是按照一定顺序传输的,有序号,接收方会根据序号的顺序对接收到的数据重新组装,从而还原。
Q:UDP怎么实现可靠传输
可以通过应用层实现,重传机制(ACK)、数据校验(每个数据报文中添加校验和)、数据序号(为每个报文添加序号,如果乱序就要求重传)、超时重传、NACK
2)TCP首部
序号:字节流编号 、确认号(ack):希望收到的下一个报文序号、
窗口:接收方能够收到的数据大小。
3)三次握手
TCP连接的建立需要进行三次握手,具体过程如下:
- 客户端向服务端发送SYN报文,并将其序列号设为随机数。此时,客户端进入SYN_SEND状态。
- 服务端接收到SYN报文后,回复一个SYN+ACK报文作为应答,并将确认号设为客户端的序列号加1。此时,服务端进入SYN_RECV状态。
- 客户端接收到服务端的SYN+ACK报文后,向服务端发送一个ACK报文,确认收到了服务端的应答。此时,客户端进入ESTABLISHED状态。服务端接收到客户端的ACK报文后,也进入ESTABLISHED状态。
至此,TCP连接建立成功,双方可以开始进行数据传输。
TCP连接的建立需要进行三次握手,目的是为了确保双方都可以收发消息,同时避免因网络延迟等原因造成的连接异常。
4)四次挥手
TCP四次挥手是指在TCP连接关闭时,客户端和服务端之间需要发送四个包来确认双方都已经关闭连接。具体过程如下:
- 客户端发送一个FIN报文给服务端,表示客户端已经没有数据要发送了。客户端进入FIN_WAIT_1状态。
- 服务端收到FIN报文后,发送一个ACK报文给客户端,表示服务端已经收到关闭请求。服务端进入CLOSE_WAIT状态,等待自己的数据发送完毕。
- 当服务端没有数据要发送时,发送一个FIN报文给客户端,表示服务端已经关闭连接。服务端进入LAST_ACK状态。
- 客户端收到FIN报文后,发送一个ACK报文给服务端,表示客户端已经收到服务端的关闭请求。客户端进入TIME_WAIT状态,等待2MSL(最长报文段生存时间)后关闭连接。服务端在收到客户端的ACK报文后,关闭连接。
在四次挥手的过程中,如果某个包丢失了,会导致连接无法关闭。因此,TCP连接的关闭过程需要保证每个包都能够正确地发送和接收。
5)TCP粘包问题,怎么解决。
粘包:多次数据发送首尾相连,无法正确区分第一二次发送多少,就是第二次读取的数据有第一次的剩余,造成了数据的污染。
解决:发送定长数据(协议固定),包头+数据,滑动窗口,设置消息边界。
滑动窗口:发送方维护一个窗口,接收方维护一个确认号。发送方每次发送数据时,会等待接收方的确认。如果接收方的确认号和窗口大小合法,则发送方会将数据放入窗口,等待接收方的确认。如果接收方的确认号和窗口大小不合法,则发送方会等待一段时间后重新发送。
滑动窗口是解决流量控制和错误控制的问题,能够避免网络拥塞和数据丢失的问题。
Q1:为什么UDP没有这个问题
因为UDP首部有16bit来指示数据报文长度,在应用层能够将报文分开。
Q2:为什么会发生粘包问题:—TCP数据发送缓冲区
当数据过大,大于发送缓冲区剩余大小时会发生拆包。
但是如果输入的数据很小,TCP会一次将缓冲区的多个数据一起发出去,发生粘包。
6)TCP短连接和长连接
短连接:连接使用后立即关闭,只会在CS指间传递一次操作。
长连接:完成一次读写之后,连接建立好以后一直保持不关闭。
7)TCP流量控制
通过动态控制发送端发送窗口的大小,实现端到端的流量控制。
拥塞窗口:由发送端维护,发送端根据当前拥塞程度来决定窗口值。
发送窗口={接受窗口,拥塞窗口}。
流控和拥塞控制区别:流控属于通信双方协商,拥塞控制涉及到通信链路全局。
8)TCP拥塞控制
会设置门限值ssthresh=16,
慢开始(指数增长),
加法增大(达到门限值后拥塞避免算法)每次加一。
当遇到第一次网络拥塞,重新定义门限值为当时拥塞窗口的一半(24—12)然后加法增大
丢包判断:1.3ACK 2.超时重传(RTO)
快重传:当遇到3ACK事件,即连续收到对同一个报文段的三个冗余ACK,重传该数据段。
快恢复:设置拥塞窗口减半(16—8)然后加法开始。
Q:为什么是3ACK ——实践经验。
超时重传:如果发送方发送数据包后在一段时间内没有收到确认信息,会重新发送数据包。
这段时间叫做RTO(重传超时时间),RTO一般=2RTT(往返时延)
9)TCP如何保证可靠传输
确认和重传,数据校验,数据合理分片和排序,流量控制和拥塞控制。
常见问题:
一.TCP UDP
1.TCP UDP的区别
总:连接,交付,拥塞流控,面向对象,传输方式。
UDP:无连接,尽最大可能交付,面向报文,支持一对一、一对多、多对多的通信,UDP是一个包一个包的传输,有边界但是可能丢包和乱序。
TCP:面向连接,可靠交付,有流控,拥塞控制,全双工通信,面向字节流,一对一(点对点)
TCP是流式传输,保证顺序和可靠。
2.如何确定一个TCP?
源地址,源端口,目标地址,目标端口。TCP四元组可以唯一的确定一个连接。
3.如何确定一个TCP的分片结束
TCP使用序列号和确认号来实现可靠传输,当收到的报文过大时,会实现分片。
在TCP首部会有MF和DF字段,MF标志是否为最后一片,DF标志为确认是否分片。
4.TCP的缺陷?
队头阻塞
TCP是面向字节流协议,要求收到的数据是完整并且有序,如果因为拥塞问题某个数据包丢失,那么在这个数据包后面的数据传输也会被阻塞,因为TCP要求数据有序传输。
解决的方法:拥塞控制机制,调整发送速率减少丢包的可能性。
5.Tcp怎么确保可靠传输
TCP的可靠传输机制:包括序号,确认机制,重传机制。
序号:面向字节流的,每一个字节都编上序号。
确认:每次发送消息同时要发送ACK包,并且使用了累计确认,即确认号表示之前的包都正确收到了
重传:有超时重传和冗余ACK两种。
超时重传是每个数据发送会有计时器,如果超时没有收到ack就会重新发送报文段
冗余ack:如果收到3ack就说明出现拥塞,就会流控减小发送窗口并重传报文。
6.如何实现一个可靠的UDP
为什么UDP可靠——具体实现——与TCP不同点。
1.QUIC协议:基于UDP的可靠传输协议
为了解决TCP产生的问题,如上队头阻塞,现在基于UDP实现了可靠传输协议。
2.主要引入了TCP类似的多路复用、流量控制、重传机制等。
保证可靠传输采用了序列号,确认机制和重传机制。
3.与TCP不同的是,QUIC协议在传输层和应用层指间加入了可靠性层,实现更好的错误恢复机制。并且使用了安全加密算法提高了数据传输的安全性。
7.Tcp序列号?
序列号:TCP协议中对数据包编号,来保证TCP连接的可靠性。每次发送一个字节序列号加一。用来解决网络包乱序的问题。
确认号:下一次期望收到的数据的序列号,用来解决丢包的问题
8.Tcp是怎么保证不重复的:序列号
TCP使用序列号来保证不重复。每个TCP数据包都有一个序列号,用来标记该数据包的位置。接收方会使用序列号来判断数据包是否已经接收过,如果该数据包的序列号与之前接收到的数据包的序列号重复,那么接收方会丢弃该数据包。
9.TCP粘包问题,怎么解决?
TCP发送数据的时候多次发送首尾相连,无法确定第一二次发送多少,第二次读取数据的时候有第一次的剩余,造成了数据的污染,出现了粘包的问题。
解决:协议固定每次发送定长的数据,或者设置边界,每次发送的时候添加特殊标志符表示一个包的结束。
10.TCP最大连接数
操作系统内核决定并且可以更改,linux中默认1024,但是更改会造成负载增加。
二:三次握手
1.TCP三次握手?
一:客户端先发送syn请求,syn=1 seq=x
二.服务端相应客户端的请求,syn=1, ack=1, seq=y ack=x+1
这个时候服务器端处于SYN_REVD状态,客户端处于SYN_SENT状态
三:客户端收到服务器端应答,发送ack确认 ack=1,seq=x+1,y+1
这个时候客户端处于ESTABLISHED状态,当服务端收到应答,也处于ESTABLISHED状态。这个时候三次我收完成,TCP正式建立连接。
2.为什么是三次握手而不是两次?
1.为了避免历史连接,防止旧的重复连接初始化造成混乱。
因为网络阻塞,导致之前发送的连接消息没有到达服务器端,这是客户端会重新发送新的syn字段,如果这时旧的syn字段到达了服务器端,就会跟客户端建立连接,造成了资源的浪费。
2.为了同步序列号,第二次连接的时候服务器端发送初始序列号给客户端,需要客户端的应答。这样才能保证双方的序列号可靠的同步。
3.第一次握手丢失?
超时重传,并且syn的序列号一样。重传的时间根据操作系统不同而不一样。
4.SYN攻击
client在短时间内伪造大量不存在的ip地址,不断地向服务器发送syn包,服务器回复确认包。但是因为是伪造的攻击,所以服务器就会一直等待回复,重发到超时,使得服务器瘫痪。
为了避免SYN攻击,可以采取以下措施:
1.限制半连接数,可以通过修改系统内核参数来控制半连接数的大小,减少受攻击的风险。
2.开启SYN Cookies,
3.使用硬件防火墙或负载均衡器,这些设备可以自动检查并过滤掉伪造的TCP连接请求。
三:四次挥手
1.四次挥手?
一:客户端向服务器端发送FIN消息,这个时候客户端处于FIN_WAIT_1,
二:服务器端收到客户端的FIN消息,发送ACK消息,并且继续发送数据seq,这个时候服务器端处于CLOSED_WAIT状态
三:服务器继续发送数据,直到发送完成,发送FIN和ACK消息,这个时候服务器处于LAST_ACK状态,客户端处于FIN_WAIT_2状态。
四:客户端发送ACK=1给客户端,处于TIME_WAIT,等待2MSL后CLOSE,这个时候四次挥手结束,TCP正式关闭连接。
2.TIME_WAIT ? 2MSL
作用:等待足够的时间保证最后的ACK能让服务器端接受,帮助其正常关闭。
客户端最后一个ACK包发出之后,等待2MSL才会关闭,用来重发有可能丢失的ACK报文。
为了确保客户端最后一个ACK能够到达服务器,会等待2MSL(最长报文生存时间),如果没有收到服务期短的回复,那么就是重新发送关闭请求,直到回复位置。
3.如果出现大量CLOSE_WAIT是什么原因,大量TIME_WAIT呢?
close_wait:服务器端才有的状态,说明没有调用close函数关闭连接,所以才会有大量的socket等待关闭。
time_wait:如果服务器端出现大量TIME_WAIT,说明主动断开了很多TCP的连接,就要问题排查。
四.流控与拥塞
1.TCP的流量控制有哪些策略?
1.TCP的流量控制主要是动态控制发送窗口的大小,实现端到端的流量控制。
拥塞窗口:主要由发送端维护,发送端根据当前拥塞程度来决定窗口值。
发送窗口={接收窗口,拥塞窗口}
流控和拥塞控制的区别:流控主要是通信双方协商窗口大小,拥塞涉及到发送链路的问题。
2.拥塞控制:主要是四个算法
慢启动:每收到一个ack,拥塞窗口会指数级增长一级,直到到达门限值。
拥塞避免:到达门限值之后,每次增长1,加法增大。
丢包判断:超时重传,3AC
拥塞发生:当计数器超时之后,可能发生了拥塞,把拥塞窗口置为1,门限值置为现在窗口的一半。
快速恢复:当遇到3ACK情况,cwnd为原来一半。然后加法增长
2.Tcp的滑动窗口
为了提高TCP发送的效率,不用发送连续等待ack,使用了窗口的概念。窗口的大小就是无需等待确认应答,可以继续发送的最大值。
滑动窗口可以动态调整,根据网络状态和数据量来决定窗口的大小,如果网络拥塞或者数据量过大,就是减小窗口的值,避免数据丢失。
滑动窗口的值由三个因素决定:发送窗口,接收窗口,拥塞窗口。
TCP的滑动窗口是用来解决流量控制和错误控制的问题,能够避免网络拥塞和数据丢失的问题。