TCP三次握手与四次挥手

来源:互联网 发布:linux如何查看ssh端口 编辑:程序博客网 时间:2024/06/05 16:50

一、TCP三次握手

所谓三次握手,就是在建立TCP连接时,需要客户端和服务端一共发送三个包。三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号并交换TCP窗口大小信息。在socket编程中,客户端执行connect( )时。将触发三次握手。如下图:

这里写图片描述

建立连接的过程:

1.第一次握手
客户端发出请求,SYN位表示连接请求。序号是1000,这个序号在网络通讯中用作临时的地 址,每发一个数据字节,这个序号要加1,这样在接收端可以根据序号排出数据包的正确顺
序,也可以发现丢包的情况,另外,规定SYN位和FIN位也要占一个序号,这次虽然没发数 据,但是由于发了SYN位,因此下次再发送应该⽤用序号1001。mss表示最大段尺寸,如果一个段太大,封装成帧后超过了链路层的最大帧长度,就必须在IP层分片,为了避免这种情 况,客户端声明自己的最大段尺寸,建议服务器端发来的段不要超过这个长度。

2.第二次握手
服务器发出应答,也带有SYN位,同时置ACK位表示确认,确认序号是1001,表⽰示“我接收到 序号1000及其以前所有的段,请你下次发送序号为1001的段”,也就是应答了客户端的连接 请求,同时也给客户端发出一个连接请求,同时声明最大尺寸为1024。

3.客户端发出回应
对服务器的连接请求进行应答,确认序号是8001。

二、TCP四次挥手

TCP的连接的拆除需要发送四个包,因此称为四次挥手(four-wayhandshake)。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。过程如下图:

这里写图片描述

关闭连接的过程:

1. 客户端发出数据包,FIN位表⽰示关闭连接的请求。
2. 服务器发出数据包,应答客户端的关闭连接请求。
3. 服务器发出数据包,其中也包含FIN位,向客户端发送关闭连接请求。
4. 客户端发出数据包,应答服务器的关闭连接请求。

下面这个图就好理解一些了:

这里写图片描述

假设Client端发起中断连接请求,就先发送FIN报文。Server端接到FIN报文后,但是如果还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以服务器端先发送ACK,告诉Client端:请求已经收到了,但是我还没准备好,请继续等待停止的消息。这个时候Client端就进入FIN_
WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,告诉Client端:服务器这边数据发完了,准备好关闭连接了。Client端收到FIN报文后,就知道可以关闭连接了,但是他还是不相信网络,所以发送ACK后进入TIME_WAIT状态,
Server端收到ACK后,就知道可以断开连接了。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,最后,Client端也可以关闭连接了至此,TCP连接就已经完全关闭了!

三、主动断开链接的一方为什么要进入TIME_WAIT状态 ?

上面提到TIME_WAIT状态要等待2MSL,MSL是最长报文长度,在RFC793建议设为2分钟,2MSL就是4分钟。
这里,为什么要主动断开链接的一方等待这个时间之后才能断开连接呢?(假如客户端主动断开链接)

1、为了保证客户端发送的最后一个ACK报文段能够到达服务器。因为这个ACK有可能丢失,从而导致处在LAST-ACK状态的服务器收不到对FIN-ACK的确认报文。服务器会超时重传这个FIN-ACK,接着客户端再重传一次确认,重新启动时间等待计时器。最后客户端和服务器都能正常的关闭。假设客户端不等待2MSL,而是在发送完ACK之后直接释放关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭连接状态。

2、他还可以防止已失效的报文段。客户端在发送最后一个ACK之后,再经过经过2MSL,就可以使本链接持续时间内所产生的所有报文段都从网络中消失。从保证在关闭连接后不会有还在网络中滞留的报文段去骚扰服务器。
注意:在服务器发送了FIN-ACK之后,会立即启动超时重传计时器。客户端在发送最后一个ACK之后会立即启动时间等待计时器。

原创粉丝点击