TCP总结及CSTP协议介绍
TCP是在OSI七层模型的传输层,用于为网络应用服务提供端到端的通信,与UDP一同作为传输层最长用的两个协议,两个协议各有特点,各自适用于不同的场景。
TCP的特点
面向连接—TCP在传输数据之前需要通过三次握手,建立一条虚拟的链路
可靠传输服务—TCP有ACK机制,对所以的数据包要进行响应确认机制,要确保对方收到数据包,而且根据滑动窗口协议,根据网络负载,自动调节发送的数据量
面向字节流—TCP对于上层传输下来的数据,以字节为单位,根据滑动窗口的大小发送,与上层传输下来的数据大小是无关的
TCP报文
源端口:2字节
目的端口:2字节
序号:4字节,TCP是面向字节流的,指发送数据的第一个字节的序号
确认号:4字节,期望收到对方下一个报文段的第一个字节序号
数据偏移:4bit,实际上指TCP首部的长度,单位4字节
保留:6bit,置零
紧急URG:为1时,表明紧急指针有效,告诉系统有紧急数据需要传送
确认ACK:为1时,确认号有效,在连接建立后所有传送的报文段ACK为1
推送PSH:为1时,接收方就立即发送TCP字节流,而不是等到缓存满
复位RST:为1时,表明需要释放连接,并重新建立
同步SYN:用来建立连接,为1时,表示是一个连接建立请求或接受报文段
终止FIN:用来释放连接,为1时,表示要求释放连接
窗口:2字节,接受窗口,从报文段的确认号算起,接受方容许对方发送的数据量
校验和:2字节,检验范围包括首部和数据,与UDP检验方法一样
紧急指针:2字节,指出报文段中紧急数据的字节数,窗口为0时,也可发送紧急数据
选项:扩展TCP的功能,最大为40字节
填充:使选项满足4字节的整倍数
数据:数据载荷
TCP三次握手四次挥手
三报文握手
第一次握手:建立连接时,客户端发送syn包(到服务器,并进入SYN_SENT状态,等待服务器确认
第二次握手:服务器收到syn包,必须确认客户的SYN,同时自己也发送一个SYN包,即SYN+ACK包,此时服务器进入SYN_RECV状态
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK,客户端和服务器进入ESTABLISHED
四报文挥手
第一次挥手:客户端发送一个FIN,用来关闭客户端到服务端的数据连接
第二次挥手:服务端收到客户端FIN,回复一个ACK,表示确认关闭
第三次挥手:服务端关闭与客户端的连接,发送一个FIN给客户端
第四次挥手:客户端发回ACK报文确认,表示确认关闭
注:客户端并不是立刻关闭连接,而是等待一段时间在关闭,是为防止之后一个ack丢失,对双方通信造成影响
滑动窗口协议
流量控制
TCP会根据自己接收缓存区的大小,动态的调整对方发送窗口的大小,保证不会因为发送方因为发送大量数据,导致自己无法接收,而出现数据丢失
接收方在发送ACK时,将自己的缓存区大小放在TCP报头的滑动窗口中,发送给发送方,发送方收到后,就会根据滑动大小,调节自己发送的数据
拥塞控制
TCP为防止将大量的数据突然注入到网络中,引起网络的负载突然加大,从而导致数据包的可能丢失,所以TCP采用拥塞控制机制,根据网络动态的改变发送窗口的大小。
慢开始:TCP连接建立以后,会以指数增长的形式发送数据,直到达到规定的门限值
拥塞控制:TCP发送的数据量达到门限值后,采取等差增长的方法,慢慢试探当前网络的最大承载量
快重传:如果发送方连续收到三个一样的ACK,表明网络发生拥堵,TCP会减少发送量,从慢开始继续发送数据
快恢复:快重传的机制,会导致网络中的数据量突然增大,又突然减小,效率不高,所以后来当TCP收到三个连续的ACK时,不在从慢开始开始,而是将自己的发送量减小一半,这样就可以提高效率
TCP所谓的加法增大,就是TCP会从慢开始,慢慢的增加发送量,乘法减小就是发生拥堵,就将自己的发送量乘以0.5
关于TCP的面试题
1、介绍TCP连接的三次握手?追问:为什么TCP握手需要三次?
【问】TCP三次握手?
TCP是一个面向连接的传输层协议,在传输数据之前,需要双方交换信息,确保双方都可以正常工作。
第一次握手:客户端请求服务端,发送syn包到服务器,并进入到SYN_SEND状态,等待服务器的回复
第二次握手:服务器收到syn包,知道有客户端向自己请求,自己准备就绪后向客户端发送ack回复报文,同时也向客户端发送syn包,这两个包是一起发送的,即ack+syn,然后服务器进入syn_recv状态
第三次握手:客户端收到ack+syn报文,确认客户端已经做好准备,然后自己准备就绪,再向服务端发送ack,自己进入ESTABLISHED状态,服务端收到ack后,也进入ESTABLISHED状态
【问】为什么TCP握手需要三次?
TCP是一个可以同时双向通信的协议,也就是全双工通信的,如果是两次握手,服务端只能确定客户端准备好发数据了,至于是否可以接受数据,服务端不知道,所以需要请求客户端,也就是需要发送4个报文,为了不浪费带宽,节约时间,就将ack和syn包合并为一个包使用,所以就是三报文握手
注:TCP连接建立完成后,发送的数据包中,ack都是置1的
2、介绍TCP的四次断开?追问:为什么TCP的挥手需要四次?
【问】TCP的四次断开?
TCP是一个可靠的传输协议,断开连接时,要保证数据传输完毕后才断开
第一次挥手:客户端向服务端发送一个fin包,并进入到fin_wait_1状态
第二次挥手:服务端收到fin包后,知道对方要断开连接,回复ack包,并进入到close_wait状态
第三次挥手:服务端向客户端发送fin包,请求断开连接,并进入到last_ack状态
第四次挥手:客户端收到ack后会进入到fin_wait_2状态,再收到fin包后会进入time_wait状态,并向服务端发送ack,服务端收到后,会关闭连接,但是客户端还有等待一段时间才会关闭
【问】TCP挥手为什么需要四次?
TCP是全双工的通信,连接的建立是双向的,所以断开连接时,需要双向断开,所以需要四个报文,和三次握手一样需要四个报文,但是为什么不能合并呢?因为单向关闭时,一个方向上已经不再通信,但是可能另一个方向正在发送数据,如果合并了就会导致数据没有发送完成就要关闭连接,所以为避免这个想象出现,两个方向需要各自单独关闭
【问】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能到CLOSE状态
如果客户端直接关闭,会有两种情况。第一种:客户端最后发送的ack丢失了,服务端没有收到,服务端就会向客户端重发fin包文,但是客户端已经关闭,就不会响应,服务端就要连续发送多个数据包,来确认对方已经无法响应,这样会影响服务端对端口的利用效率。第二种:如果客户端直接关闭端口后立刻有新的连接建立,但是应为网络延迟,服务端还没有关闭,并且向客户端发送了fin报文,这样就会对新的连接诶造成干扰。
3、TCP的syn攻击过程?追问:怎么防御
【问】TCP的syn攻击过程?
TCP的syn攻击发生在TCP的三报文握手的第一报文握手阶段,当服务端收到客户端的syn报文,就会将该半连接添加到半连接队列,保存客户端的信息,等待客户端的响应,但是客户端并没有响应第二次握手,这就导致该半连接信息会长时间驻留在半连接队列中,如果有大量的此类信息,就会导致半连接队列被填满,正常用户的连接就无法被服务端接受,就会造成DOS攻击。
【问】syn攻击如何防御
syn攻击的防御方法很多,比如检查IP地址、减少服务器的重发次数和等待时间、syn防火墙等,但是这样都没有办法有效的解决syn攻击。但是syn_cookie可以解决syn攻击,cookie是服务端发送给客户端的随机信息,客户端发送syn给服务端,服务端不在保存半连接,而是返回cookie给客户端,如果如果客户端要建立连接,就要使用cookie去连接服务器。服务端保存的只有cookie信息,有效的解决服务端资源占用问题
4、为什么连接的时候是三次握手,关闭的时候确实四次握手?
TCP是面向连接的全双工通信,需要双向连接,也就是是需要四个报文,但是三次握手将第二个和第三个合为一个数据包,所以是三次握手。关闭的时候,不能同时关闭的原因是另一条数据路径上可能正在发送数据,所以双向需要单独关闭,需要发送四个报文
5、TCP是如何通过滑动窗口协议实现流量控制和拥塞避免的?
【一】流量控制
接收方可以通过数据包控制发送方发送的数据量,让数据量维持到自己可以接受的范围内,是一种端到端的控制,滑动窗口协议会维持一个可变的窗口,在窗口内的数据才会被发送,这个窗口的大小是有对端可以控制的
【二】拥塞避免
为避免将大量的数据输入到网络中,TCP会将数据慢慢的输入到网络,然后探测网络的最大传输上限,如果发现有网络拥塞,就会立刻减少发送的数据量,然后再慢慢探测,增加自己的发送量,具体的算法:慢开始、拥塞控制、快重传、快恢复
6、TCP与UDP区别
TCP是面向连接的,UDP是无连接的
TCP通过可靠的传输服务,UDP是尽最大努力交付,不保证可靠性
TCP占用资源高,UDP占用资源少
TCP传输效率低,延时高,UDP传输效率高,延时低
TCP面向字节流,对数据分段,UDP面向数据包,不对数据分段,直接交付给网络层
7、TCP的定时器?
【问】TCP常见的四种定时器?
TCP虽然有ACK机制提供可靠的确认机制,但是如果ACK丢失,就可能会造成死锁的情况,所以TCP就设置了几种定时器,解决死锁的情况
重发定时器:如果ACK报文在传输的过程丢失,发送方就可能一直等待对方的ACK,而对方认为自己已经发送了ACK,就等待对方发送数据,这样就会发生死锁,所以重传定时的作用就是在一定时间内没有收到对方的回复,就重新发送请求,这个时间大约为2*RTT
坚持定时器:原因TCP的流量控制机制,如果接受方缓存区满,就会将自己的滑动窗口设置为零,而发送方就会等接受方处理完数据再发送,但是接受方处理完数据,会向发送方请求发送,但是该报文丢失了,这样就会造成死锁,所以坚持定时器的作用就是每隔一段时间向接受方发送一次探测,询问是否可以接受
保活计数器:保活定时器是为防止对方突然无法通信,还没有来的及断开连接,为返回本地一直等待对方响应,就设置一个保活机制,如果在一段时间内没有收到消息,就自己断开连接
时间等待计时器:该计时器用于四次挥手的最后一次,为防止最后一个ACK丢失,而设置的时间,在时间内TCP的连接并非立刻关闭,而是等到该计时器结束才关闭,一般为2msl
SCTP协议
SCTP (Stream Control Transmission Protocol)是一种传输协议,在TCP/IP协议栈中所处的位置和TCP、UDP类似,兼有TCP/UDP两者特征。
TCP是一种面向连接的协议,提供可靠传输,确保数据有序发送;
UDP是一种面向消息的协议,不能确保数据有序发送
SCTP是后来引入的一种新的协议,提供了和TCP一样的可靠、有序的数据传输功能,同时却能和UDP一样面对消息的方式来进行操作,保护消息边界
特性
1、多宿主
TCP是将点到点的连接,就是一个TCP连接对应的是一对ip地址
SCTP可以将多个路劲并到一个联合中,数据可以在任意一个连接路径上传输,可以通过多对的IP地址建立一个聚合的连接
2、多流
在一个联合中,可以同时传输多个流,每个流都是独立的,并且有各自的编号
3、初始化保护
TCP建立连接需要三次握手,但是容易遭受syn攻击,但是SCTP使用4次握手机制,4次握手机制和TCP_cookie的机制类似,客户端请求服务端,服务端会返回客户端一个cookie,客户端需要拿cookie去请求服务端,服务端才会建立连接,并返回ack
4、消息分帧
TCP是根据字节来传输的,不关心上层数据的结构,是不是一个数据,而是将这些数据看成字节流来发送,然后由接收端自行分组,如果一个应用程序发送两条消息,TCP可能会将这个两条消息组成一个TCP报文,然后再有接收端自行拆分
UDP是将上层数据封装后直接交给网络层
SCTP在这一块的处理是与UDP一致的,应用程序有两个消息,这两个消息会分别用SCTP报文传输
5、平滑关闭
TCP和SCTP都是基于连接的协议
TCP中连接的删除是半关闭的,服务的某一端可以关闭自己这端的socket,但是可以继续接受数据。
SCTP没有采用TCP的关闭机制,而是双向直接关闭,也就是三次挥手,SCTP和TCP的连接的建立和关闭,正好相反
6、可配置的无序发送
TCP的消息发送是有顺序的,按照缓存序列中的顺序发送
UDP是直接将上层数据发送,接受方可能会因为网络延迟,收到数据包的顺序不同
SCTP可以有序发送,也可以配置为无序发送