TCP

发布于:2024-04-03 ⋅ 阅读:(98) ⋅ 点赞:(0)

TCP

可靠传输是tcp最为重要的核心(初心)

可靠传输,并不是发送方把数据能够100%的传输给接收方

而是退而求其次

让发送方发送出去数据之后,能够知道接收方是否收到数据。

一但发现对方没有收到,就可以通过一系列的手段来进行补救



1.确认应答

确认应答就是用来判断接收方是否能够收到数据。

发送方,把数据发送给接收方之后,接收方收到一个数据之后就会返回一个应答报文。

发送方如果收到了这个应答报文就知道自己的数据是否发送成功了。

在网络中可能会出现一些信息丢失的情况如下

A先发给B一个咱们下午去吃自助餐,然后又发了一个咱们组队学习吧

B回应给好啊,又发送一个滚吧。

正常的情况下A收到回复明白了咱们下午去吃自助餐,但是不组队学习

但是不知道什么原因A先收到了滚吧,在收到好啊就理解为咱们组队学习下午不吃自助餐 。

这样收到的回应的顺序不同造成的误解很使人困扰。在实际的网络传输中就也有可能会出现这样的后发先致的情况(一个数据包在传输的过程中,走的路径可能是非常复杂的,不同的数据报走的不同的路线)。

TCP解决上述个问题需要完成两个工作

1.确认应答报文和发送出去的数据,能够对上号,不要出现歧义。

2.确保在出现后发先致的现象下,能够让应用程序这边仍然按照正确的顺序来理解数据。

TCP中的32位序号位和32位确认号位就会在发送信息时进行标记,然后如果出现后发先致,就让其等待至先发的到来。如下述例子

A先发给B一个咱们下午去吃自助餐(标记为1),然后又发了一个咱们组队学习吧(标记为2)

B回应给好啊(针对1的确认序号1),又发送一个滚吧(针对2的确认序号2)。

这样就通过序号了描述了数据的先后顺序。

此图只是粗略的形容了一下大概的工作流程实际中序号并不是按照这样一条两条来进行编号,而是按照字节来编号(TCP面向字节流)

 

如图所示,一个TCP包中一共有1000个字节的载荷数据。其中第一个字节的序号是1,就在TCP报头的序号字段中写1.

由于一共是1000个字节,最后一个就是1000,但是1000这样的数据并没有在TCP报头中记录。TCP报头中记录的序号,是这一次传输的载荷数据中的第一个字节的序号。其他字节的序号需要一次的推出。

在应答报文中就会在确认序号字段填写1001

因为收到的数据是1-1000,所以1001之前的所有数据,都被B收到了或者也可以理解为B向A要从1001开始的数据。

通过特殊的ack数据包,里面携带的”确认序号“告诉发送方,哪些数据已经被确认收到了.

此时发送方,心中就有数了,知道自己刚发的数据是到了还是没到。也就构成了可靠传输的核心部分。

TCP的初心是为了实现可靠传输  达成可靠传输的最核心的机制就是确认应答。

如何区分一个数据包是普通的数据还是ack应答数据?

如图所示

当ACK这一位为1时,表示当前的数据包是一个应答报文,此时该数据包中的确认序号字段就能够生效。

这一位为0时,表示当前数据包是一个普通报文此时数据包是一个普通报文。此时数据包中的确认序号字段是不生效的。

TCP这里的常见面试题:通过确认应答为核心借助,借助其他机制辅助,最终完成可靠传输。

不是三次握手四次挥手保证了可靠传输,这是建立连接的。

2.超时重传

确认应答,描述的是一个比较理想的情况

如果网络传输过程中,出现了丢包操作??怎么解决

发送方肯定就无法接收到ACK。

为什么会出现丢包??

网络如同现实生活中的公路一样,错综复杂,并且有很多的收费站

平常如果车流量不大的时候,车会很快通过收费站,很少出现堵车

但如果到节假日,收费站肯定会出现堵车

网络中的收费站可以理解为是一些路由器/交换机

如果数据包太多了就会在这些路由器/交换机上出现堵车

但是路由器针对堵车的处理往往粗暴,不会把这些积压得数据包都保存好,而是将其中得大部分数据包之间丢弃掉,这个数据包直接消失了在网络中。

丢包是一个随机得事情,在上述tcp传输过程中,丢包存在两种情况

1.传输的数据丢失了

2返回的ACK丢失了

发送方无法区分这两种情况,所以无论出现哪种情况发送方都会进行重新传输。

第一次是丢失了,重传一下试试,很大概率能传过去

假设丢包的概率是20%,两次都丢包的概率是4%,重传就大幅度的提升了数据会被传输过去的概率,重传操作是一个很好的丢包补救措施。

注:引入了可靠性,会付出代价。最明显的代价两方面

1.传输效率

2.复杂程度

发送方何时进行重传?等待时间(初始的等待时间是可以配置的。不同系统的时间不一定一样,也可以通过修改一些内核参数来进行改变时间,等待的时间也会进行动态变化,每多经历一次超时,等待时间都会变长)

发送方发出数据之后,会等待一段时间。如果这个时间之内,ack到达了,被视为数据到达。如果到达这个时间,数据还没到就会触发超时重传

例如

A->B发了一条数据,
第一次,A等待ACK的时间,假设是50ms

此时如果达到50ms,还没有ack,A就重传.
当A重传的数据,还是没有收到ack,第二次等待的时间就会比第一次更长
拉长也不是无限拉长,重传若干此时,时间拉长到一定程度,认为数据再怎么重传也没用了,就放弃 tcp连接(准确的说是会触发tcp的重置连接操作)


 

根据上图站在B的角度来看,收到了两条一样的数据,收到了重复的数据,是否会给程序带来一些bug,比如发一条,收的时候收到了两条一模一样的数据。

TCP帮我们解决了这个问题,TCP有一个接收缓冲区(内存空间),会保存当前已经收到的数据,以及数据的序号。接收方如果发现,当前发送方发来的数据,是已经在接收缓冲区中存在的(收到过重复的数据),接收方就会直接把后来这个数据给直接丢弃掉,确保应用程序读的时候,只能读到一条数据。

接受缓冲区不仅能进行去重,还能进行重新排序。确保发送的顺序和接受的顺序是一致的。

3.连接管理

建立连接+断开连接

三次握手和四次挥手

tcp这里的握手,就是给对方传输一个简短的,没有业务数据的数据包,通过这个数据包,来唤起对方的注意,从而触发后续的操作。

握手这个操作,不是TCP独有的,甚至不是网络通信独有的,计算机中的很多操作,都会涉及到握手     

TCP的三次握手,TCP在建立连接的过程中,需要通信双方一共”打三次招呼“才能完成建立连接的。

A想和B建立连接,A就会主动发起握手操作,实际开发过程中,主动发起的一方,就是客户端,被动接受的一端就是服务器。

同步报文段,就是一个特殊的TCP数据包,没有载荷的(不携带业务数据的应用层数据包)

握手完成,A和B记录了对方的信息(构成了逻辑上的连接)。

建立连接的过程,其实是通信双方都要给对方发起syn,也要给对方反馈ack。一共是4次握手了,但是中间两个可以合并成一次。

        上图中的syn这一位为1表示这个报文段是同步报文段,如果是1不是同步报文段。

三次握手是要解决什么问题??


 

TCP初心,是为了实现"可靠传输”
进行确认应答和超时重传有个大前提,当前的网络环境是基本可用的,通畅的.
如果当前网络已经存在重大故障了,此时,可靠传输,无从谈起.

三次握手的核心作用一:
确认当前网络是否是通畅的

三次握手核心作用二:

要让发送方和接受方都能够确认自己的发送能力和接受能力均正常

三次握手核心作用三:
让通信双方,在握手过程中,针对一些重要的参数,进行协商
 

握手这里要协商的信息,其实是有好几个的。
大家要知道, tcp通信过程中的序号从几开始,就是双方协商出来的(一般不是从1开始的)
每次连接建立的时候,都会协商出一个比较大的,和上次不太一样的值.|

 


 


网站公告

今日签到

点亮在社区的每一天
去签到