TCP的连接不是真正意义上的
连接
,而是通过序列号和ACK来维护一个概念上的“”连接“
TCP的特点是可靠性传输
那么它是如何在不可靠的IP协议之上实现可靠的呢?
主要是这几点:
1.序列号和ACK
2.超时重传
3.检验和纠错
从TCP的三次握手开始
分为 请求方 和 接收方
1.请求方发送一个分组,其中将SYN置为1,并且将seq随机置数a作为初始序列号 ——–并且转为SYN_SENT状态
简单来说就是SYN就是发送一个连接请求,顺便告诉接收方,我这个发送序列是从a开始的
2.接收方收到请求,并且向请求方发送一个分组,其中ACK=a+1,seq随机置数b作为初始序列号———并且转为SYN_SENT状态
接收方说:我收到了你的请求,并且我希望接受到你发送序号为a+1的数据,我的发送序列是从b开始的
3.请求方收到分组,并且回应分组:其中ACK=b+1,seq置为a+1———并且转为ESTABLISHED状态
4.接受方收到分组 ,检查ACK是否为b+1———并且转为ESTABLISHED状态
此时双方都为ESTABLISHED状态 ,表示连接成功,双方可以正式发送接受数据
其中ACK既可以表示收到了对方发来的信息,其中的值也是希望得到的信息序列
在无序的网络中,数据包可以通过不同的路线发送到接收方,TCP并不是维护一条路径唯一的连接,而是通过序列号和ACK来保证维护一条虚拟的”连接“
如果所有数据都可以保证
按时到达
的话,TCP已经实现了可靠,但是!!!在网络中,无论是路由器的丢包,还是因为物理设备落后导致的阻塞都是很常见的问题,所以为了安全和效率,必须要有
超时,重传
等流程
TCP拥有一个“
滑动窗口
”协议,即发送方维护一个发送窗口表示
发送分组但并未完成确定
和
未发送但可以发送的分组
的区间,这同时意味着区间的左边都是完成发送并完成确认的分组 , 区间的右边是未发送也暂时不允许发送的分组
1.发送窗口只有收到发送窗口内字节的ACK确认,才会移动发送窗口的左边界。
2.接收窗口只有在前面所有的段都确认的情况下才会移动左边界。当在前面还有字节未接收但收到后面字节的情况下,窗口不会移动,并不对后续字节确认。以此确保对端会对这些数据重传。
3.遵循快速重传、累计确认、选择确认等规则。
4.发送方发的window size = 8192;就是接收端最多发送8192字节,这个8192一般就是发送方接收缓存的大小。
通常,TCP会维护一个定时器,以及一个动态RTT,客户端到服务端往返的时间,如果一个数据序列a发送出去,如果在RTT内没有收到ACK的话,客户端就会重发,并且重新设置RTT。
如果超时,TCP会降低当前数据发送率,通常通过基于拥塞控制机制减少发送窗口大小或者增大RTO的退避因子实现。
所谓的拥塞控制机制…
解决的丢包的保证了所有数据一定能到达后,为了保证可靠性,还必须去判断数据是否被修改或者损坏,此时就需要去检验和纠错
TCP会保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段(也就是要求发送端重发)