计算机网络
TCP
TCP基本认识
由于TCP是面向连接,能保证数据的可靠性交付,因此常用于
- FTP文件传输
- HTTP/HTTPS
TCP三次握手四次挥手
三次握手
第一次握手:
客户端将TCP报文标志位SYN设置为1,随机产生一个序号值seq=J,保存在TCP首部的序列号字段里,指明客户端打算连接的端口,并将该数据包发送给服务端,发送后客户端进入SYN_SENT状态,等待服务器确认。
第二次握手
服务端收到数据包后根据SYN=1知道客户端请求连接,同时将SYN=1,ACK=1,确认好ack=J+1,随机产生一个序号值sql=K,发送给客户端,服务器进入SYN_RCVD状态
第三次握手
客户端接收后,确认ack是否为J+1,标志位ACK是否为1,如果正确将ACK=1,确认号ack=K+1并发到服务端,服务器收到数据判断ack是否为K+1,ACK是否为1,如果是则建立连接,客户端和服务端进入ESTABLISHED状态。
四次挥手
第一次挥手
客户端将FIN设置为1,seq设置为u(前面已经传过来数据的数据的最后一个字节的序号加一),此时客户端进入FIN_WAIT_1状态
第二次挥手
服务器接收数据后,从FIN=1判断为断开连接,设置ACK=1,ack=u+1,sql=v,服务端进入CLOSE_WAIT状态,TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,此时处于半关闭状态,即客户端已经没有数据要发送了,但是服务器发送数据,客户端依然要接收。
客户端收到确认请求后,客户端进入FIN_WAIR_2状态,等待服务器大宋连接释放报文(在此之前还要等待服务器发送最后的数据)
第三次挥手
服务器将最后的数据发送完毕后,就像客户端发送连接释放报文FIN=1,ack=u+1,由于处于半关闭状态,可能发送了一些数据,假设seq=w,服务器进入LAST_WAIT状态
第四次挥手
客户端收到释放请求后,必须发出确认ACK=1,ack=w+1,自己的序列号seq=u+1,客户端进入TIME_WAIT状态。此时TCP连接还没有释放,必须经过最长报文寿命的时间后,客户端依然没有收到回复,才会进入CLOSED状态
服务器只要收到了客户端的确认,就立即进入CLOSED状态。所以服务器结束TCP连接的时间比客户端更早。
为什么连接的时候是三次握手,断开是四次挥手
因为简历连接时,服务器可以直接发送SYN和ACK报文,其中ACK是用来确认的,SYN是用来同步的,所以连接只需要三次握手。
但是关闭连接时,服务端收到FIN报文时,可能还有其他数据要发送,所以只能先回复ACK报文,剩余数据发送完后才能发送FIN报文,因此要四次握手,
为什么要三次握手
- 如果两次握手,客户端发送的第一个连接请求报文并没有丢失,而是延误了很才到达服务端,但是服务器此时收到失效的连接请求后,就误认为是新的连接请求,于是向客户端发送确认报文。
但是此时客户端没有发送连接请求,因此并不会回复服务端的确认请求,但服务端却以为新的连接已建立,并一直等待客户端发送数据,浪费资源。 - 如果使用两次挥手,可能产生死锁。加入Client给Server发送一个连接请求,Server收到了请求,并发送确认消息确。按照两次握手的约定,Server认为连接已经建立了,可以开始发送数据。但是如果在Server发送给Client的确认请求在传输中丢失的情况下,Client并不知道Server已经确认,在这种情况下Client并不知道连接已建立成功,将忽略Server的数据,仍在等待Server发送确认应答,而在Server发送超时后,重复发送同样的数据,这样就造成了死锁。
如果连接已建立客户端出现故障怎么办
TCP有一个保活计时器,Server每一次收到Client请求都会复位这个计时器,默认是两小时,如果两小时后还没有收到Client的任何数据,Server就会发送一个探测报文段,以后每隔75S发送一次报文,如果连续发送10个报文仍然没有反应,则Server就认为Client出现了故障,接着关闭连接。