为什么?
为了确保可靠的建立与终止连接
三次握手过程?
过程图解
(Client主动打开连接,Server被动打开连接)
各次握手详解
1.向server发送请求报文段
客户端将报文段中的SYN=1,并选择一个seq=x,(即该请求报文的序号为x) 将这个报文发送到服务器。
2.server向client发送确认(同意连接)
SYN=1,ACK=1,并选择一个seq = y,且报文中确认号ack=x+1,序号为y .此时服务器进入同步已接收状态(SYN-RCVD)。
3.client对server的确认的确认
将ACK=1,确认号为y+1,而报文首部的序号为x+1,将该报文发出后,客户端进入已连接状态(ESTABLISHED)。
第二次握手的必要性
TCP是面向连接的,一次握手肯定建立不了连接
确认的确认(第三次握手的必要性)
主要是为了防止造成网络资源的浪费。假设当client想要建立连接时发送一个SYN,然后等待ACK,结果这个SYN因为网络问题没有及时到达server,于是再发送一个SYN,server成功收到后面的ACK后,client发送的第一个SYN终于到达,对于server来说这是一个新连接请求,然后server又为这个连接申请资源,返回ACK,并一直等待client发来数据,造成server的很多资源白白浪费!
面试题:握手失败后的处理
作者:骨气
链接:https://www.nowcoder.com/discuss/8081?type=1&order=0&pos=105&page=1
来源:牛客网
当客户端收到服务端的SYN+ACK应答后,其状态变为ESTABLISHED,并会发送ACK包给服务端,准备发送数据了。如果此时ACK在网络中丢失,过了超时计时器后,那么Server端会重新发送SYN+ACK包,重传次数根据/proc/sys/net/ipv4/tcp_synack_retries来指定,默认是5次。如果重传指定次数到了后,仍然未收到ACK应答,那么一段时间后,Server自动关闭这个连接。但是Client认为这个连接已经建立,如果Client端向Server写数据,Server端将以RST包响应,方能感知到Server的错误。
当失败时服务器并不会重传ack报文,而是直接发送RTS报文段,进入CLOSED状态。这样做的目的是为了防止SYN洪泛攻击。
参考:http://www.cnblogs.com/heyonggang/p/3386415.html
四次挥手过程?
过程图解
(数据传输结束后,client和server都处于established状态)
各次挥手详解
1.向server发送连接释放报文段,同时停止再发送数据
客户端将文段首部的终止控制为FIN置1,序号seq=u,客户端进入FIN-WAIT-1状态(等待服务器的确认)。
2.server向client发送确认
令ACK=1,确认序号ack = u+1,自己的报文序号seq=v,发送后,服务器进入CLOSE-WAIT状态(关闭等待);
此时TCP连接进入连接半关闭状态,服务器可能还会向客户端发送一些数据;
即从服务器到客户这个方向的连接还没有关闭,服务器可以向客户端发送数据,反过来不行。
3.向client发送连接释放报文
令FIN=1,ACK=1,确认号ack =u+1,自己的序号seq = w(w可能等于v也可能大于v),服务器进入LAST-ACK状态(最后确认)。
4.server向client发送确认
客户端收到服务器的连接释放报文后,对该报文发出确认,令ACK=1,确认号ack=w+1,自己的序号seq=u+1,发送此报文后,等待2个msl时间后,进入CLOSED状态。
msl时间
最长报文段寿命,第四次挥手后进入TIME-WAIT状态,经过客户端时间等待计时器设置的2msl时间后,才能进入closed状态,完全释放TCP连接。
等待两个msl时间的必要性
(1)为了保证客户端发送的最后一个ACK报文段能够到达服务器
(2)为了防止上面说的“已失效的连接请求报文段”出现在本连接中
服务器与客户端状态变化
客户端状态变化:未连接----->SYN-SEND----->ESTABLISHED----->FIN-WAIT-1----->FIN-WAIT-2----->TIME-WAIT----->CLOSED
服务器状态变化:未连接----->SYN-RCVD----->ESTABLISHED----->CLOSE-WAIT----->LAST-ACK----->CLOSED
名词解释
SYN(synchronous建立联机)
ACK(acknowledgement 确认)
PSH(push传送)
FIN(finish结束)
RST(reset重置)
URG(urgent紧急)
Sequence number(顺序号码)
Acknowledge number(确认号码)
establish 建立,创建