# TCP的定义
TCP全称Transmission Control Protocol(传输控制协议),是一种面向连接的,可靠的,基于字节流的传输层通信协议。TCP是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。 暂时无法在飞书文档外展示此内容
三次握手
什么是三次握手
第一次握手
服务端新建套接字,绑定地址信息后开始监听,进入LISTEN状态。客户端新建套接字绑定地址信息后调用connect,发送连接请求SYN,并进入SYN_SENT状态,等待服务器的确认。 SYN = 1,ACK=0表示该报文段为连接请求报文。 x为本次TCP通信的字节流的初始化序号。TCP规定:SYN=1的报文段不能有数据部分,但要消耗掉一个序号。
第二次握手
服务器端一旦监听到连接请求,就会将连接放入内核等待队列中,并向客户端发送SYN和确认报文段ACK:SYN=1,ACK=1,seq=y,ack=x+1,进入SYN-RCVD状态。 SYN = 1,ACK = 1表示该报文段为连接同意的应答报文。 Seq = y ,表示服务器作为发送者时,发送字节流的初始序号。 Ack = x+1表示服务器端希望下一个数据发送序号从x+1开始的字节。
第三次握手
客户端收到SYN+ACK报文后向服务器端发送确认报文段ACK(ACK=1,seq=x+1,ack=y+1),表示服务端发来的连接同意应答已经成功收到。并进入ESTABLISHED状态,,开始读写数据。服务器一旦收到客户端的确认报文,就进入ESTABLISHED状态,此时连接的建立完成!
为什么握手是三次,而不是两次或四次
tcp通信需要确保双方都具有数据收发的能力,得到ACK响应则认为对方具有数据收发的能力,因此双方都需要发送SYN确保对方具有通信的能力。 第一次握手是客户端发送SYN,服务端接收,服务端得出客户端的发送能力和服务端的接收能力都正常;(买家向卖家付款,证明有购买能力) 第二次握手是服务端发送SYN+ACK,客户端接收,客户端得出本地和服务器的发送接收能力都正常,但是此时服务器并不能确认客户端的接收能力正常;(卖家向买家出示收款证明,买家可以知道自己的钱已经发送到) 第三次握手客户端发送ACK,服务器接收,服务器才能得出客户端及服务器自己发送接收能力正常。 所以两次的话握手是不安全的,四次的话就多余了,浪费资源。
三次握手可以携带数据吗?
三次握手中只有第三次是可以携带数据的,
tcp三次握手失败,服务器怎么处理
握手失败的原因
- 服务端没有收到SYN,则什么都不做
- 服务器回复了SYN+ACK后,长时间没有收到ACK响应,超时后就会发送RST重置连接报文,释放资源
ISN
isn代表什么:
是TCP发送方的字节数据编号的原点,告诉对方我要开始发送数据的初始化序列号。
isn是固定不变的嘛?
如果是固定的,攻击者很容易猜出后序的确认号,为了安全起见,避免被第三方猜到从而发送伪RST报文,所以ISN是动态生成的。
什么是半连接队列
服务器第一次收到客户端的SYN之后,就会处于STN_RECD状态,此时双方都还没有完全建立连接。 服务器会把这种状态下的请求放在一个队列里面,我们把这种队列称为半连接队列 还有一个全连接队列,就是已经完成了三次握手,建立起来连接的就会放在全连接队列中,如果队列满了就有可能出现丢包现象。
四次挥手
什么是四次挥手
TCP连接的拆除需要发送四个包,因此称为四次挥手,客户端或服务器都可以发起挥手动作。
刚开始双方ESTABLISHED状态,假如是客户端先发起的关闭请求,四次挥手如下:
第一次挥手
客户端向服务器发送一个FIN报文,报文中指定了一个序列号,此时客户端处于FIN_WAIT状态。 即发出连接释放报文段(FIN=1,序号seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN_WAIT(终止等待1)状态,并等待服务器确认。(买家第二批货不要了,没继续给卖家打钱,取消订单,但之前的第一批货还是要的)
第二次挥手
服务端收到FIN之后,会发送ACK报文,并且把客户端的序列号值+1作为ACK报文的序列号值,表明已经收到客户端的报文了,此时服务器处于CLOSE_WAIT状态。 即服务端收到连接释放报文段后即发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v),服务器进入CLOSE_WAIT(关闭等待)状态,此时如果服务器有数据要发送的话,客户端依然需要接受,此时的TCP处于半关闭状态,客户端收到服务器的连接释放。客户端收到服务端的确认之后,进入FIN_WAIT(终止等待2)状态,等待服务端发出的连接释放报文段。(买家等着卖家把第一批货发来,并退还第二批的钱,同时卖家对未发完的货物进行打包发给买家)
第三次挥手
服务器也想断开连接了,向客户端发送FIN报文,且指定一个序列号,此时服务端处于LAST_ACK的状态。 即服务端没有要向客户端发出的数据,服务端发出连接释放报文段(FIN = 1,ACK = 1,序号seq = w,确认号 ack =u+1),服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。 (卖家等待买家收到退款和货物后回个话)
第四次挥手
客户端收到服务端的连接释放报文之后,对此发出确认报文段(ACK = 1,seq = u+1,ack = w+1),客户端进入TIME-WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。而服务器收到结束报文的ACK后,进入CLOSED状态,断开连接。
为什么需要四次挥手
在握手的时候,客户端将SYN包和ACK包合并到一个包中发送,所以减少了一次包的发送。 对于四次挥手,由于TCP是全双工通信,主动关闭方发送FIN请求不代表完全断开连接,只能表示主动方不再继续发送数据; 接收方可能还要发送数据,就不能够立即关闭服务器端到客户端的数据通道,所以就不能将服务器端的FIN包和对客户端的ACK包合并发送,只能先确认ACK,等服务器无需发送数据的时候再发送FIN包。
TIME_WAIT状态的作用
如果主动关闭方进入CLOSED状态后,被动关闭方发送FIN包后没有得到ACK确认,超时后就会重新发送一个FIN包。倘若客户端没有TIME_WAIT而直接进入CLOSED状态,下次启动新的客户端就有可能使用与之前客户端相同的地址信息,有两个危害:
- 刚启动的新得客户端收到服务器重新发送的FIN包,对新的连接造成影响
- 该客户端向相同的服务端发送SYN连接请求,但服务器处于LAST_ACK状态,要求收到的是ACK而不是SYN,会发送RST重新建立请求。
TIME_WAIT等待2MSL进入CLOSED状态的原因
MSL指的是报文在网络中最大的生存时间。 在客户端发送对服务端的FIN确认包ACK之后,这个ACK包有可能到达不了,服务器如果接收不到ACK包就会重新发送FIN包。 所以客户端发送ACK包之后需要留出2MSL时间(ACK到达服务器——服务器回传FIN重传包,一来一回)等待确认服务器端确实收到ACK包。 如果客户端等待2MSL也没收到服务器的重传FIN包,就可以确认服务器已经收到客户端发送的ACK包。
一台主机上出现大量的TIME_WAIT是什么原因
TIME_WAIT是主动关闭的一方出现的,一台主机上出现大量的TIME_WAIT证明这台主机发起了大量的主动关闭连接。 解决:
- 可以调整TIME_WAIT的等待时间
- 开启套接字地址重用选项。
一台主机上出现大量的CLOSE_WAIT是什么原因
CLOSE_WAIT是被动关闭方收到FIN请求进行回复之后的状态,等待上层程序进一步处理,若出现大量CLOSE_WAIT,有可能是被动关闭方主机程序中忘记了最后一步断开连接后调用close释放资源。 解决:
- 加上对应的close即可解决问题。
tcp连接管理中的保活机制
tcp通信中,若两端长时间没有数据往来,则这时候每隔一段时间,服务器会向客户端发送一个保活探测数据包,要求客户端进行回复。 若连续多次没有收到响应,就认为连接已经断开。
长时间:7200s 每隔一段时间:75s 连续多次无响应默认为9次