beihai2024 发表于 2024-4-7 17:09

tcp相关学习



TCP 会保证每一个报文都能够抵达对方,它的机制是这样:报文发出去后,必须接收到对方返回的确认报文 ACK,如果迟迟未收到,就会超时重发该报文,直到收到对方的 ACK 为止。

比如说 我们给服务器发送了 一个 client hello

那么接下来 我们会首先收到服务器发过来的ack 包 当然这个ack包 是在tcp层面的

在应用层面 我们是感知不到这个ack包的

然后接下来才是 服务器发给我们 server hello 包


<div>TCP 报文发出去后,并不会立马从内存中删除,因为重传时还需要用到它。</div>

那这种情况下 我们就需要注意一个情况 那就是双方网络连接通路状况比较差的情况下

有可能就会导致 tcp的 报文很多 留在了 内核缓冲区里面

一旦缓冲区满了我们应用程序层面 再往 缓冲区 塞东西就塞不下去了 就会 block 住 等待系统缓冲区留出来位置

如果 TCP 是每发送一个数据,都要进行一次确认应答。当上一个数据包收到了应答了, 再发送下一个。这个模式就有点像我和你面对面聊天,你一句我一句,但这种方式的缺点是效率比较低的。

tcp的特点就是可靠性 这里面的可靠性 包括两个意思 就是报文一定会送达 然后顺序一定是正确的顺序

面向连接:一定是「一对一」才能连接,不能像 UDP 协议 可以一个主机同时向多个主机发送消息,也就是一对多是无法做到的;

可靠的:无论的网络链路中出现了怎样的链路变化,TCP 都可以保证一个报文一定能够到达接收端;

字节流:消息是「没有边界」的,所以无论我们消息有多大都可以进行传输。并且消息是「有序的」,当「前一个」消息没有收到的时候,即使它先收到了后面的字节已经收到,那么也不能扔给应用层去处理,同时对「重复」的报文会自动丢弃。

要实现这样的可靠性 那么怎么设计这个协议呢

tcp的协议设计 如果说 每一个客户端发给服务器的包 服务器都会对应回一个ack给客户端

然后客户端每次都等这个ack接收到之后 再发下一个报文这样做确实是可行的 可以实现可靠的效果

但是 这样 客户端每次只能发一个报文效率就比较低

-------------------------------------------------------------------------------------------------------------------------------------------------

TCP可以考虑成古代的骑马送包裹

假设从广东送4096斤黄金 到京城去

注意一个骑手骑着马 然后带的包裹重量是有限制的所以要分开来发送

而且要求最后交到和珅手上的时候 黄金的顺序是不能乱的


三、MTU
MTU是最大传输单元,这个根据由具体的网络决定的,如以太网MTU=1500,Internet的MTU=576。

如果IP层所要传输的数据长度>MTU的话,要对这个数据进行分片处理,每个片长度都小于MTU,每个片构成一个IP数据报进行传输。

在服务端的IP层使用IP数据报的首部信息对这些分片的IP数据报进行重组。这样使得IP层的分片对传输层看起来是透明的(传输层不知道IP层进行了分片操作)也就是说 一个骑手最多就只能携带1500斤
所以要发4000斤到京城那么可以这样设计

一个骑手带着1500斤到京城去 送到京城驿站(京城的内核缓冲区) 之后再回来 回到广州之后 也就是广州收到京城的ack了

京城驿站告诉广州驿站收到这个1500斤的包裹了

那么继续出发 再带着1500斤再到京城去
然后再带着ack回来

这样子设计没有问题 可靠性得到了保障包裹的顺序是不会出错

唯一问题是 效率太差了

那么改进的设计

就是同时让3个骑手出发 每个人带1000多斤那么4000斤黄金就一起朝着京城驿站出发了

但是这里面就有问题 因为这三个骑手 在路上 有快有慢其中还有骑手可能会被谋杀掉了(丢包)

或者说三个骑手都顺利到达了京城驿站但是顺序不一样 有可能3号骑手反而第一个到达

所以这里面要考虑 丢包重传的问题 然后就是顺序的可靠性的保证问题

丢包重传需要考虑 等待多久 才认为 这个包已经被谋杀掉了 客户端需要重新传

而且ack包也有可能丢掉 也就是服务器实际收到了这个包 并且把这个ack包发出去了

但是客户端收不到的情况?


<p style="margin: 10px auto; color: rgb(0, 0, 0); font-family: verdana, sans-serif; font-size: 13px;">四、MTU分片的一个问题
(1)如果IP层每个分片都正确到达目的端,那自然是很好的。但是如果IP层在发送端对要发送的数据(TCP报文段)进行分片操作,但是在传输过程中某个分片发生了错误,这样会使整个TCP报文段重传。因为IP层不负责可靠性(超时和重传),可靠性有传输层提供。</p><p style="margin: 10px auto; color: rgb(0, 0, 0); font-family: verdana, sans-serif; font-size: 13px;">这也是TCP对数据分段的一个原因,分段后的数据在往下交付后肯定不会超过MTU,这样避免了因为分片而带来的的麻烦。</p><p style="margin: 10px auto; color: rgb(0, 0, 0); font-family: verdana, sans-serif; font-size: 13px;">(2)如果UDP进行数据传输的话,UDP将应用层交付下来的整个数据封装为UDP数据报(没有像TCP分块的操作)。这样IP层的数据很容易超过MTU,造成数据分片。而TCP的数据分块,不会导致IP层的分片。</p>
<div><span style="color: rgb(0, 0, 0); font-family: verdana, sans-serif; font-size: 13px;">总的来说UDP不会分段,就由IP来分片。TCP分段,也就不用IP来分片了!</span></div>



TCP (传输控制协议) 是一个面向连接的协议。发送方发送数据,接收方会对其响应ACK,如果接收方没有按时响应ACK,发送方将重传数据。



页: [1]
查看完整版本: tcp相关学习