一、需要用到的几个基础概念
序列号Sequence Number(seq):第一次发数据包时会随机生成一个。
确认号Acknowledgment Number(ack):它的值是接收到的数据包的序列号加1。
标志位:
SYN:同步标志位,它的值为1表示是一个请求建立连接的数据包。
ACK:确认标志位,它的值为1表示确认号是有效的。
FIN:结束标志位,它的值为1表示没有数据要发送了。
二、Tcp三次握手:

- 第一次握手:客户端发送连接请求数据包,设置SYN=1,随机生成一个序列号seq=x,客户端进入SYN_SENT状态。
- 第二次握手:服务端收到客户端连接请求的数据包,对数据包进行确认,将确认号ack设置为x+1,同时设置SYN=1、ACK=1、seq=y,将包含这些信息的数据包发送给客户端,服务端进入SYN_RCVD状态。
- 第三次握手:客户端收到服务端发送的数据包,然后设置ACK=1、ack=y+1,并将包含这些信息的数据包发送给服务端,发送成功后,客户端和服务端都处于ESTABLISHE状态,建立连接成功。
Tcp为什么要三次握手,两次为什么不行?
主要是为了延迟时间过长的报文突然发送到服务器,如果客户端发送一个请求连接的报文,而这个报文因为网络等一些因素导致长时间没有到达服务器,这时候就会重发一次报文,如果重发的这次连接成功后,第一次延迟的报文又突然到达了服务器,这个报文应该是失效的,此时:
如果是两次握手,那么服务端收到已经失效的报文,并且回复了确认报文就会直接建立连接(因为不需要客户端在次确认了),并没有丢弃掉它。
如果是三次握手,服务端收到已经失效的报文,并且回复了确认报文,但是客户端并不会在给服务端发送确认报文,服务端收不到确认报文就认为该连接无效。
三、Tcp四次挥手:

- 第一次挥手:客户端发出请求关闭连接数据包,设置FIN=1,ACK=1,seq=m(当前的序列号),此时说明客户端已经没有要发送的数据了,客户端进入FIN_WAIT_1状态。
- 第二次挥手:服务端收到了客户端请求关闭连接的数据包,服务端向客户端发送一个确认数据包,设置ACK=1,seq=n(当前的序列号),ack=m+1,服务端进入CLOSE_WAIT状态,此时服务端可能还有没有发送完的数据。
- 第三次挥手:服务端将数据发送完毕,就会向客户端发送关闭连接数据包,设置FIN=1,ACK=1,seq=w(在第二步的时候可能又向客户端发送了一些数据,假设当前的序列号是w),ack=m+1,服务端进入LAST_ACK状态。
- 第四次挥手:客户端收到服务端发送的FIN数据包,向服务端发送确认数据包,然后客户端进入TIME_WAIT状态,服务端收到确认数据包后就关闭连接。客户端不会马上关闭,而是会等待2MSL的时间,在等待的这段时间如果没有收到服务端的回复,说明服务端已经正常关闭了,客户端也可以关闭了。
客户端为什么最后还要等待2MSL而不是立刻关闭?
2MSL是报文段最大生存时间,为了防止客户端最后一次给服务端发送的报文丢失,如果客户端最后一次给服务端发送的确认报文没有到达服务端,那么服务端就会在次发送请求关闭的报文,而这个时候客户端可以继续接收并回应。
2433

被折叠的 条评论
为什么被折叠?



