TCP协议

TCP是面向连接的,可靠的,基于字节流的传输层通信协议。
特点:
* 基于连接的:数据传输之前需要建立连接
* 全双工的:双向传输
* 字节流:不限制数据大小,打包成报文段,保证有序接收,重复报文自动丢弃
* 流量缓冲:解决双方处理能力的不匹配
* 可靠的传输服务:保证可达,丢包时通过重发机制实现可靠性
* 拥塞控制:防止网络出现恶性拥塞

* Sequence Number(序列号)是记录包中的序号,TCP会按照报文字节进行编号,它是用来解决包在网络中乱序的问题
* Acknowledgement Number(确认号)确认序列号,是用于向发送方确认已经收到了哪些包,用来解决不丢包的问题
* Windows(窗口)也叫Advertised-Windows,也就是著名的滑动窗口,主要是用来解决流控的

TCP连接管理

一、TCP连接:

四元组[源地址,源端口,目的地址,目的端口]

二、确立连接:TCP三次握手
* 同步通信双方初始序列号(ISN, initial sequence number)
* 协商TCP通信参数(MSS,窗口信息,指定校验和算法)

客户端和服务器初始状态下都处于CLOSED状态,主动打开连接的为客户端,被动打开连接的是服务器。

  1. TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态
  2. (第一次握手)TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,设置报文首部中的SYN=1,同时选择一个初始序列号seq=x,此时TCP客户端进程进入SYN-SENT(同步已发送)状态。TCP规定SYN报文段不能携带数据,但需要消耗掉一个序号
  3. (第二次握手)TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中包含ACK=1,SYN=1,确认号是ack=x+1,自己初始化一个序列号seq=y,此时TCP服务器进程进入SYN-RCVD(同步收到)状态
  4. (第三次握手)TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定ACK报文段可以携带数据,但是如果不携带数据则不消耗序号
  5. 当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了

为什么TCP客户端最后还要发送一次确认呢?

主要防止已经失效的连接请求报文突然又传送到服务器,从而产生错误
如果使用的是两次握手,当客户端发送的第一个请求连接因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送连接报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时之前滞留的那一次请求连接到达了服务器,这个报文本该失效的,但是两次握手的机制将会让客户端和服务器再次建立连接,导致不必要的错误和资源的浪费
如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务器接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认,由于服务器收不到确认,就知道客户端并没有请求连接

三、关闭连接:TCP四次挥手

数据传输完毕后,双方都可以释放连接,最开始的时候,客户端和服务器都是处于ESTABLISHED状态,然后客户端主动关闭,服务器被动关闭。
1.(第一次挥手)客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序列加1),此时客户端进入FIN-WAIT-1(终止等待1)状态
2.(第二次挥手)服务器收到连接释放报文,发出确认报文ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时服务器进入CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间
3.客户端收到服务器的确认请求后,此时客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后数据)
4.(第三次挥手)服务器将最后的数据发送完毕后,就向客户端发送连接释放报文FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送一些数据,假定此时的序列号为seq=w,此时服务器就进入LAST-ACK(最后确认)状态,等待客户端的确认
5.(第四次挥手)客户端收到服务器的连接释放报文后,必须发送确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2*MSL(报文最大生存时间)后,当客户端撤销相应的TCB后,才进入CLOSED状态
6.服务器只要收到客户端发出的确认,立即进入CLOSED状态,同样撤销TCB后结束这次的TCP连接。可以看到服务器结束TCP连接的时间要比客户端早一些

为什么客户端最后还要等待2MSL?

MSL(Maximum Segment Lifetime),TCP允许不同的实现可以设置不同的MSL值
第一,保证了客户端发送的最后一个ACK报文能够达到服务器,因此这个ACK报文可能丢失,站在服务器的角度上看,服务器已经发送了FIN+ACK报文请求断开了,客户端还没有回应,导致服务器会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出响应报文,并且会重启2MSL计时器
第二,防止类似已经失效的连接请求报文段出现在本连接中,客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,这样新的连接中不会出现旧连接的请求报文

字节流协议

TCP是一个字节流的协议,TCP把应用交付的数据仅仅看成一连串的无结构的字节流,TCP并不关心应用程序一次将多大的报文发送到TCP的缓存中,而是根据对方给出的窗口值和当前网络拥堵的程度来决定一个报文段应该包含多少个字节。
如下图所示,假设在一个网络的数据传输过程中,传输20个字节(远比实际中小)的数据,在传输过程中会把数据切成segment分段传输,所以会出现0123这四个字节先到,导致乱序的问题,此时TCP会根据每段数据报文的序列号进行重排序,同时还会处理数据重复、数据缺失等问题。这就是TCP基于字节流协议要做的任务。

数据可靠性传输

一、停止等待协议(效率低):

二、重传机制:
1.ack报文丢失

2.请求报文丢失

三、滑动窗口协议与累计确认(延迟ack)

由于之前的传输方式是一次只发送一个报文,效率比较低,现在一次发送五个报文12345,如果服务器只接受到了1245,没有收到3报文,则会告诉客户端,让客户端重新发送3报文或者3之后的报文(345)。

参考资料

1.https://blog.csdn.net/qzcsu/article/details/72861891

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值