三次握手:
第一次握手:
客户端向服务端发送请求连接报文段,即SYN=1,seq=x,并进入SYN_SENT状态,等待服务端的确认;
第二次握手:
服务端收到客户端的请求连接报文段,如果同意连接,向客户端发送确认报文段,即发送SYN=1,ACK=1,seq=y,ack=x+1,并进入SYN_RCVD状态,为本次连接分配TCP缓存和变量
第三次握手:
客户端收到服务端的确认报文段之后,向服务端给出确认报文段,即ACK=1,seq=x+1,ack=y+1,并且该本次的连接分配缓存和变量,此时客户端和服务端都进入ESTAB_LISHED状态,三次握手完成,连接成功。
四次挥手:
由于TCP连接是全双工的,所以每个方向都必须单独进行关闭操作,当一方完成数据传送的任务的时候,可以通过发送一个FIN来终止该方向的连接;收到一个FIN只能意味着这一个方向上没有数据流动,一个TCP连接在收到一个FIN之后仍能够进行数据发送。首先进行关闭的一方为主动关闭,而另一方执行被动关闭。
第一次挥手:
客户端发送FIN=1,seq=u的报文段给服务端,用来关闭客户端到服务端的数据传送,此时客户端进入FIN_WAIT_1状态;
第二次挥手:
服务端收到客户端发过来的FIN报文段之后,给客户端发回ACK确认报文段,即ACK=1,seq=v,ack=u+1,此时服务端进入FIN_WAIT状态,发送成功之后,客户端进入FIN_WAIT_2状态;
第三次挥手:
服务端关闭与客户端的连接,即发送FIN=1,ACK=1,seq=w,ack=u+1报文段给客户端,此时,服务端处于LAST_ACK状态;
第四次挥手:
客户端发送确认报文段给服务端,即发送ACK=1,seq=u+1,ack=w+1,此时,客户端进入TIME_WAIT状态。
TCP的扩展问题:
问题一、TCP连接为什么是三次握手,将三次握手改为两次握手可以吗?
TCP连接的三次握手是为了防止已经过期的连接再次连接上。考虑这样一种情况,在网络拥堵的情况下,如果客户端向服务端发送连接请求SYN1,但是连接请求SYN1没有及时到达。这时候,客户端认为连接请求SYN1丢失,会再次发送连接请求SYN2,当SYN2到达的时候,服务端回复确认ACK,若是基于两次握手,则此刻客户端和服务端连接成功,当客户端和服务端数据传输完成之后,两者断开连接。但是在断开连接之后,连接请求SYN1到达服务端,此时服务端回复确认ACK,两者在两次握手的原则下再次连接成功。深入引入到TCP源码,ack的处理方式。tcp_ack()函数胡,处理已经过期的ack采用丢弃方式进行处理。在以上实例做那个客户端虽然丢弃了服务端发送的ACK,但是服务端并不知道。所以在服务端上这是一个成功的连接。
问题二、TCP连接可不可以设置成三次挥手?
不可以!三次挥手代表:当服务端收到客户端的FIN1的时候,将ACK和FIN2同时发送给客户端,客户端回复ACK2,完成三次挥手。如果这样的话则相当于在四次挥手的基础上去除了服务端收到FIN1回复ACK后的CLOSE_WAIT状态,那么如果服务端发送缓冲区或者网络结点上还有发送给客户端未发送完成的数据,而且FIN2先于数据到达客户端,会造成数据的丢失。
问题三、为什么在四次挥手结束的过程中,客户端进入TIME_WAIT状态时等待2MSL?
1、为了保证客户端发送的最后一个ACK报文段能够到达服务端。这个ACK报文段有可能会丢失,因而处于LAST_ACK状态的服务端收不到已经发送的FIN+ACK报文段的确认。服务端会超时重传这个FIN+ACK报文段,而客户端就有可能在2MSL时间之内收到这个重传的FIN+ACK报文段。如果客户端在TIME_WAIT状态的时候不等候一段时间,而是在发送完ACK确认报文段之后直接释放连接,那么此时就无法收到客户端超时重传的FIN+ACK报文段,因此也不会再发送一次确认报文段,那么服务端就无法进入CLOSED状态。
2、客户端在发送完ACK报文段之后,再经过2MSL时间,就可以使本连接持续的时间所产生的所有报文段都会从网络中消失,这样就可以使得下一次新的连接中不会出现这种旧的连接请求的报文段。
TCP与UDP之间的区别?
TCP | UDP | |
是否连接 | 有连接 | 无连接 |
可靠性 | 可靠的 | 不可靠 |
服务类型 | 流失服务 | 数据报服务 |
首部字节数 | 20 | 8 |
检验和 | 必需的 | 可选的 |
通常为“远程连接”(经过许多的路由器和网桥等中间设备) | 通常为本地通信 |