tcp是主机对机的传输控制协议,采用流式服务,提供面向链接,可靠的链接服务
采用三次握手建立客户端与服务器之间的链接:
三次握手是在客户端执行connect(向服务器发起链接)时开始的
先看一下三次握手的过程
1.服务器通过listen调用进入LISTEN状态,被动等待客户端链接
2.客户端向服务器端发送SYN(请求链接),此时客户端进入SYN_SENT状态
3.服务器端监听到有链接请求,将该链接放入内核等待队列(listen时创建)中,并向客户端发送带有SYN标志的确认报文段(ACK),此时链接进入SYN_RCVD状态
4.客户端收到服务器的确认报文段,再给服务器回馈一个ACK,若客户端一定时间内没有回馈,则会引发服务器的超时重传机制
5.即链接建立成功,处于ESTABLISHED状态
- 为什么必须是三次握手,不是两次或四次??
两次的话,只能是没有最后一次ACK确认报文段,但这是不安全的操作,有可能服务器的SYN没发送到对端,也可能客户端刚收到数据,就断掉了,这都能导致链接建立失败。
ACK确认报文段都只是对有效数据(SYN)进行确认,最后一次ACK确认报文段就是对上一次的SYN进行确认的,不需要再对确认报文段进行确认,所以不需要第四次握手了
三次握手的时机:客户端调用connect时发生,在服务器端调用listen之后,accept之前完成
客户端和服务器任意一端close()即触发四次挥手
(此处以客户端断开连接为例)
1.客户端主动断开链接(向服务器端发送FIN结束报文段),此时客户端处于FIN_WAIT1状态
2.服务器端收到客户端的断开请求后回复ACK确认报文段,并进入CLOSE_WAIT状态,客户端处于FIN_WAIT2状态(可能服务器端还有一些数据还没传送完毕)
3.等到服务器端完成所有数据传输后,向客户端发送FIN结束报文段,并进入LAST_ACK状态
4.客户端收到服务器的断开连接请求后,会发送ACK确认报文段,并进入TIME_WAIT状态
5.断开连接完成
-
可能是三次挥手吗?
可能,在服务器端收到客户端的FIN结束报文段后,服务器端直接发送带有确认信息的结束报文段,而不是先发送ACK,再发送FIN -
TIME_WAIT(存在于主动断开链接的那一端)
1,保证可靠的终止掉链接。若客户端发送ACK后不等待,直接关闭,但是ACK在传输过程中丢失了,服务器端没有收到Adequate确认消息,会再次发送FIN给客户端,而此时客户端已经关闭,没人处理这条消息2,保证迟来的数据报,能被识别并丢弃。若客户端在FIN_WAIT_2状态,服务器在向客户端发送数据,但是FIN比数据的传输速度快,若客户端一收到FIN,发送ACK后直接关闭,那么服务器发送的迟来数据将不能被处理继续占用之前绑定的端口号
客户端链接TIME_WAIT等待的时间是2MSL(MSL 报文段最大生存时间)