TCP协议讲解(二)——三次握手和四次挥手

关于TCP协议报文格式及相关解释和传递数据的方式,可以移步我的另一边文章:TCP协议讲解(一)
我们说TCP提供了一种面向连接的、可靠的字节流服务,面向连接指的就是每次传输数据前,都要建立连接;

可靠性:

1.应用数据被分割成TCP认为最适合发送的数据块。这和UDP完全不同,应用程序产生的数据报长度不变。

2.当TCP发出一个段后,它启动一个定时器,等待目地端确认收到报文段。如果不能及时收到一个确认,将重发这个报文。

3.当TCP收到另一端的数据,他将发送一个确认,但并不是立即确认,将推迟几分之一秒。

4.TCP将保持它首部和数据的检验和,这是一个端到端的检验和,目的是检测数据字传输过程中的任何变化。如果收到的检验和有误,TCP将丢失这个报文段和不确认收到此报文段(希望发送端超时重发)。

5.IP数据可能会失序,那TCP作为上层协议,如有必要,可以对数据进行重排序,再向上提交。

6.IP数据有可能重复,则TCP接收端必须丢弃重复数据。

7.TCP控制流量,固定的缓冲区只允许另一端发送接收端可以接纳的数据,这将导致较快主机致使较慢主机的缓冲区溢出。

面向连接:

TCP的三次握手和四次挥手:

三次握手:
三次握手

三次握手的原理与上一篇一致,A发送seq=200,SYN=1给B,A进入SYN_SEND状态,B回复时ACK=1,表示此次为回复,并将seq=201,同时SYN=1,在发送seq=500,B进入SYN_RECE状态,A收到后,发送序号seq=201,确认数据=501,同时ACK=1表示回复,A进入SYN_RECE状态

为什么3次?2次不行吗?
不行,如果是2次握手,A先发一个SYN给B,但是这个SYN因为某些原因没及时到达B,所以A在一定时间后会重发,B会回一个ACK,但是这时候第一个SYN到达了,此时对B来说,这个是一个新的请求,所以会返回ACK,但对A来说,这个SYN是一个无效的请求,并不会处理这个ACK,而B并不知道A不会处理,导致B一直在等待,造成资源浪费。

四次挥手:
三次握手

客户端发送主动请求,FIN=1,seq=u,客户端进入FIN-WAIT-1阶段,服务端收到请求后回复确认报文ACK=1,seq=v,ack=u+1,服务端进入CLOSE-WAIT状态,TCP服务器通知高层的应用进程,此时客户端已经没有进程要发送了。客户端收到信息后就进入FIN-WAIT-2状态;服务端将最后的数据发送完后即向客户端发送链接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能发送了一些数据,seq=w,服务器进入LAST-ACk,即最后确认状态。客户端收到请求后,回复ACK=1,ack=w+1,自己的序列号为seq=u+1,客户端进入TIME-WAIT状态,此时TCP链接还没有释放,必须经过2*MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED阶段。服务端只要收到客户端发送的确认就立即进入CLOSED状态,撤销TCB,所以服务端比客户端结束的要早。

为什么客户端需要2*MSL才关闭?

作为一个软件开发工程师,我不想去研究这个。大体原因有2个:

1.确定服务端可以收到这个ACK,因为可能会丢失,如果没收到,服务端就会给客户端再发一次,所以客户端等一段时间,如果没收到服务端重发的报文,就说明没有问题。

2.防止类似于“三次握手”中,已经失效的请求连接重新出现在本次连接体系中的情况。客户端发送完最后一个确认报文后,在这个时间里,可以使本次连接中所有的报文都从网络中消失,即耗死它,这样新连接中不会出现旧的连接。

为什么建立连接需要3次握手,断开却需要4次挥手?

这是TCP的半关闭造成的,TCP即然是全双工的,所以每个方向必须单独的进行关闭。建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。

而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值