什么是三次握手
- 第一次握手:client将SYN置1,随机产生一个初始化序列seq发送给server,同时自己进入SYN_SENT(同步发送)状态
- 第二次握手:server收到client的SYN=1之后,知道客户端请求建立连接,将自己的SYN置,ACK置1,产生一个acknowledge number = sequence number+1,并随机产生一个自己的初始序列号,发送给客户端,进入SYN_RCVD(同步接收)状态;
- 第三次握手:客户端检查acknowledge number是否为序列号+1,ACK是否为1,检查正确之后将自己的ACK置为1,发送给服务器,进入ESTABLISHED(已建立连接)状态;服务器检查ACK为1和acknowledge number为序列号+1之后,也进入ESTABLISHED状态;完成三次握手,连接建立。
TCP建立连接可以两次握手吗,为什么?
不可以,原因有两个:
- 首先,可能会出现已失效的连接请求报文段又传到了服务器端。
- client 发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达 server。本来这是一个早已失效的报文段。但 server 收到此失效的连接请求报文段后,就误认为是 client 再次发出的一个新的连接请求。于是就向 client 发出确认报文段,同意建立连接。假设不采用 “三次握手”,那么只要 server 发出确认,新的连接就建立了。由于现在 client 并没有发出建立连接的请求,因此不会理睬 server 的确认,也不会向 server 发送数据。但 server 却以为新的运输连接已经建立,并一直等待 client 发来数据。这样,server 的很多资源就白白浪费掉了。采用 “三次握手” 的办法可以防止上述现象发生。例如刚才那种情况,client 不会向 server 的确认发出确认。server 由于收不到确认,就知道 client 并没有要求建立连接。
- 其次,两次握手无法保证client正确接收第二次握手的报文(server无法确认client是否收到),也无法保证client和server之间成功互换初始序列号。
可以采用四次握手吗?为什么?
可以,但是会降低传输的效率。
四次握手是指:第二次握手:server只发送ACK和acknowledge number;而server的SYN和初始序列号在第三次握手时发送;原来协议中的第三次握手变为第四次握手。出于优化的目的,四次握手中的二、三可以合并。
第三次握手中,如果客户端的ACK未送达服务器,会怎样?
server端:
由于server没有收到ACK确认,因此会重发之前的SYN+ACK(默认重发5次,之后会自动关闭连接进入CLOSED状态),client收到后会重新传ACK给server
client端,两种情况:
- 在server进行超时重发的过程中,如果client向服务器发送数据,数据头部的ACK是为1的。所以服务器收到数据之后会读取ACK number,进入establish状态。
- 在server进入closed状态之后,如果client向服务器发送数据,服务器会以RST(复位)包应答。
如果已经建立了连接,但客户端出现了故障怎么办?
服务器每收到一次客户端的请求后都会重新复位一个计数器,时间通常设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没有反应,服务器就认为客户端出了故障,接着就关闭连接。
初始序列号是什么?
TCP连接的一方是A,随机选择一个32位的序列号(Sequence Number)作为发送数据的初始序列号(Initial Sequence Number,ISN),比如为1000,以该序列号为原点,对要传送的数据进行编号:1001、1002...三次握手时,把这个初始序列号传送给另一方B,以便在传输数据时,B可以确认什么样的数据编号是合法的;同时在进行数据传输时,A还可以确认B收到的每一个字节,如果A收到了B的确认编号(acknowledge number)是1001,就说明编号为1001-2000的数据已经被B成功接受。
什么是四次挥手
- 第一次挥手:client将FIN置为1,发送一个序列号seq给server;进入FIN_WAIT_1状态;
- 第二次挥手:server收到FIN之后,发送一个ACK=1,acknowledge number=收到的序列号+1;进入CLOSE_WAIT状态。此时客户端已经没有要发送的数据了,但仍可以接受服务器发来的数据。
- 第三次挥手:server将FIN置为1,发送一个序列号给client;进入LAST_ACK状态;
- 第四次挥手:client收到服务器的FIN后,进入TIME_WAIT状态;接着将ACK置1,发送一个acknowledge number=序列号+1给服务器;服务器收到后,确认acknowledge number后,变为CLOSED状态,不再向客户端发送数据。客户端等待2*MSL(报文段最长寿命)时间后,也进入CLOSED状态。完成四次挥手。
为什么不能把服务器发送ACK和FIN合并起来,变成三次挥手(CLOSE_WAIT状态的意义是什么)?
因为服务器收到客户端断开连接的请求时,可能还有一些数据没有发送完,这时先回复ACK,表示收到了断开连接的请求。等到数据发完之后再发FIN,断开服务器到客户端的数据传输。
如果第二次挥手时服务器的ACK没有送达客户端,会怎样?
客户端没有收到ACK确认,会重发FIN请求
客户端TIME_WAIT状态的意义是什么?
第四次挥手时,客户端发送给服务器的ACK有可能丢失,TIME_WAIT状态就是用来重发可能丢失的ACK报文,如果server没有收到ACK,就会重发FIN,如果client在2*MSL的时间内收到了FIN,就会重新发送ACK并再次等待2MSL,防止server没有收到ACK而不断重发FIN
MSL(Maximum Segment Lifetime),指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需要的最大时间。如果直到2MSL,client都没有再次收到FIN,那么client推断ACK已经被成功接收,则结束TCP连接。
评论