TCP三次握手
TCP头部有哪些字段?
tcp报文段 : tcp头部+tcp数据部分
tcp头部:
源端口:16位
目的端口:16位
序号:32位
确认号:32位
数据偏移:4位
保留:6位
窗口:16位
校验和:16位
紧急指针:16位
选项和填充:最多为40字节
控制位:
URG:紧急指针标志,为1时标识紧急指针有效,该报文应该优先传送,为0则忽略紧急指针
ACK:确认序号标志,为1时表示确认号有效。携带ACK标识的TCP报文段被称为确认报文段
RST:重置连接
SYN:表示请求建立一个连接
FIN:用于释放连接
PSH:为1表示带有push标志的数据,优先将这个报文提交给应用程序,而不是缓冲区排队
tcp头部的最长是60字节
数据部分:。。。
回答:tcp头部主要是源端口、目的端口、序列号、确认号、标记位:SYN、RST、ACK、FIN、头部长度、窗口大小,可扩展的选项等
其中序列号和确认号的大小为32位,序列号保证数据的有序性,接收方按照发送方顺序发来的数据来组装有序的数据;确认号保证数据的可靠性,当发送方已发送的数据,超过一段时间没收到确认报文,就会重传报文。
源端口和目的端口的大小是16位,源端口是发送方的端口号,目的端口是接收方使用的端口号,端口的作用是标识TCP连接是哪个进程
TCP三次握手连接过程
客户端和服务端一开始都处于close状态,服务端会监听一个端口,处于listen状态
第一次握手:客户端产生随机初始化序号,放到tcp报文头部的序号字段,同时把SYN标志设置位1,标识SYN报文。接着把SYN报文发送给服务端,之后客户端处于SYN_SEND状态
服务端收到SYN报文后,服务端也生成随机初始化序号,放到TCP报文头部的序号字段中,对客户端的初始化序号+1作为确认号,放到TCP报文头部的确认应答字段中,并将SYN和ACK标志设置为1,表示SYN-ACK报文,把报文发送给客户端,之后服务端处于SYN_RECD状态
客户端收到服务端SYN-ACK报文后,客户端发送一个ACK确认报文,该报文的确认号为服务端的初始化序号+1,并将ACK标志设置为1。客户端处于ESTABLISHED状态
服务端收到ACK确认报文,服务端也处于ESTABLISHED状态
以上就是TCP三次握手的过程
为什么需要三次握手?两次握手不行吗?
避免历史连接的建立,避免资源浪费
三次握手可以确认客户端和服务端是否同时具备发送和接收的能力
如果第二次握手丢包,会发送什么?
超时重传机制,第二次SYN-ACK报文中有
第二次报文中的ACK,是第一次握手的确认报文,那么当第二次报文丢包时,会导致客户端一直没有接收到ACK而触发超时重传机制,重传SYN包,即第一次握手
第二次报文中的SYN,是服务端建立TCP连接的报文,当第二次报文丢失后,客户端没有发送ACK报文,服务端没有收到第三次握手,于是服务端会触发超时重传机制,重传SYN-ACK报文
如果第三次握手丢包,会发生什么?
我的理解是第三次握手如果发生丢包,服务端会迟迟接收不到第三次握手的ACK包,触发超时重传机制,服务端会重新发生第二次握手的SYN-ACK包,直到最大重传次数的限制,或者收到第三次握手
TCP的半连接队列和全连接队列?
在tcp三次握手的时候,linux内核会维护两个队列,分别是:
syn队列:半连接队列
accept队列:全连接队列
服务端收到客户端发起的SYN请求后,内核会将为握手完成的连接存储到半连接队列,等待完成三次握手后转移到全连接队列
全连接队列:服务端收到客户端的第三次握手,内核会将连接从半连接队列移除,然后创建新的完全连接,并将其添加到全连接队列,等待进程调用accept函数将连接取出
TCP四次挥手
TCP四次挥手的过程
tcp的四次挥手(断开连接)是可以客户端或者服务端断开
客户端关闭连接,此时会发生一个fin报文,之后客户端进入fin_wait_1状态,
服务端收到fin报文后,将向客户端发送ack报文,接着服务端进入close_wait状态
客户端接收到ack应答报文后,之后进入fin_wait_2状态
等待服务端处理完数据后,向客户端发送fin报文,服务端进入last_ack状态
客户端收到服务端的fin报文后,回一个ack应答报文,客户端进入time_wait状态
服务端接收到ack报文后,进入close状态,至此服务端完成连接的关闭
客户端在time_wait状态经过2MSL一段时间后,自动进入close状态,至此客户端也完成连接的关闭
为什么TCP需要四次挥手?
TCP是全双工协议,双方都具有发送和接收的能力,那么断开连接的期间,要确保双方能发送完自己的数据
当客户端想要断开连接,发送fin报文给服务端,服务端接收到fin包后返回一个ack报文,但是此时还不会立即断开连接,因为服务端可能还有数据需要发送,需要等待数据发送完成后,由服务端主动发送fin报文给客户端,表示数据发送完成了可以断开连接。所以第二次和第三次挥手通常不会合并一起发送,而是分开发送,所以需要四次挥手
如果只有三次挥手,那么就可能出现一方还要数据没有发送完就被迫关闭连接,这就会导致数据的丢失
TIME_WAIT是如何产生的?
当TCP连接的主动关闭方关闭连接时,与被动方进行了四次挥手的时候,在主动关闭方发送完第四次挥手后,也就是最后一个ack报文,主动关闭方的TCP连接回会进入time_wait状态,这个状态会维持2MSL的时间,以确保对方接收到最后一个ACK报文
TIME_WAIT过多有什么危害?
占用系统资源,比如内存资源,线程资源等(服务端TIME_WAIT过多)
占用端口资源,端口资源是有限的(客户端TIME_WAIT过多)
TDP和UDP
TCP和UDP有什么区别?
连接、可靠性、传输方式
TCP是面向连接的协议,在发送数据的时候需要进行三次握手;而UDP是无连接的协议,可以直接发送数据
TCP会通过超时重传、流量控制、拥塞控制保证数据的可靠性;而UDP不考虑数据的可靠性
TCP发送的数据是以字节流的形式,没有边界;而UDP是一个包一个包的发送,是有边界的
什么时候用TCP?什么使用用UDP?
如果关注数据的可靠性和有序性,可以选择TCP,比如FTP协议,HTTP协议都是基于TCP协议进行传输数据
如果需要数据快速传输和实时性,不在意某些数据包的丢失,可以考虑UDP,例如视频会议、直播等场景
视频会议用的是UDP还是TCP?如果使用TCP发送丢包会怎么样?
视频会议使用的是UDP,因为视频会议的实时性很重要;UDP协议的实时性比TCP协议更好,采用UDP协议传输音视频的话,如果发生了丢包,只会出现一瞬间的卡顿,丢失该时刻的视频和音频,还可以继续进行沟通;如果采用TCP协议,由于TCP的可靠传输,如果发生丢包,可能画面会卡住不动,等待丢包重传才会推进画面,这样实时性就比较差了
UDP怎么改造为可靠运输?
在应用层实现,添加序列号字段和确认号字段,实现超时重传机制;
开辟缓冲区,实现滑动窗口,不仅可以实现流量控制还可以控制拥塞
UDP和TCP可以共用一个端口吗?
可以,socket是根据五元组信息唯一确认的:协议类型、源ip地址、源端口、目标ip地址、目标端口,只要有一个信息不同,就认为是不同的socket,不会引起冲突,所以TCP和UDP可以使用一个端口号
TCP可靠性
TCP的可靠性如何保证?
建立连接:三次握手,确保双方都有接收和发生数据的能力,避免历史数据的建立
超时重传机制:如果发生方迟迟没有接收到回文,就会触发超时重传机制,重新发送报文
滑动窗口机制:tcp有流量控制机制,可以根据接收方的滑动窗口大小来发送报文,避免报文发送的数据太大,导致接收方接收不了数据导致丢包
拥塞控制:tcp有拥塞控制机制,通过慢启动、拥塞避免、拥塞发送等算法调整发送速率避免网络拥塞。当网络出现拥塞时,TCP会降低发送速率,减少网络负载,保证数据的可靠传输
TCP流量控制和拥塞控制有什么区别?
流量控制是端到端,保护接收方不被数据淹没
拥塞控制是网络层面的控制,保护网络不被过载
滑动窗口是怎么实现的?解决什么问题?
滑动窗口在发送方和接收方都有一个缓冲区,在发送方表示可发送的最大数据量,在接收方表示可接收的最大数据量
发送方有了滑动窗口后,那么发送方可以不用等待接收方的确认报文,就可以继续发送下一批数据,提高传输效率
接收方有了滑动窗口后,可以实现流量控制,让发送方按照自己的接收情况来发送数据,避免对方发送数据太快,导致接收方处理不过来