4.21 用了 TCP 协议,数据一定不会丢吗?

目录

数据包的发送流程:

建立连接时丢包

流量控制丢包

网卡丢包

RingBuffer过小导致丢包

网卡性能不足

接收缓冲区丢包

两端之间的网络丢包

ping命令查看丢包:

mtr命令:

发生丢包了怎么办

用了TCP协议就一定不会丢包吗​编辑

这类丢包问题怎么解决?


数据包的发送流程:

举例简单聊天软件数据包的发送流程:

用户A和用户B两端先会通过三次握手,建立TCP连接。

        一个数据包从聊天框里发出,消息会从聊天软件所在的用户空间拷贝到内核空间发送缓冲区(send buffer),数据包就这样顺着传输层、网络层,进入到数据链路层,在这里数据包会经过流控(qdisc),再通过RingBuffer发到物理层的网卡。数据就这样顺着网卡发到了纷繁复杂的网络世界里。这里头数据会经过n多个路由器和交换机之间的跳转,最后到达目的机器的网卡处。

         此时目的机器的网卡会通知DMA将数据包信息放到RingBuffer中,再触发一个硬中断给CPU,CPU触发软中断让ksoftirqd去RingBuffer收包,于是一个数据包就这样顺着物理层,数据链路层,网络层,传输层,最后从内核空间拷贝到用户空间里的聊天软件里。

4.21 用了 TCP 协议,数据一定不会丢吗?_第1张图片

建立连接时丢包

TCP三次握手后半连接队列,全连接队列满了,丢弃新来的包

流量控制丢包

让数据按一定的规则排个队依次处理,qdisc(Queueing Disciplines,排队规则),这也是我们常说的流量控制机制。

ifconfig命令下查看到txqueuelen后面的数字1000,其实就是流控队列的长度。

当发送数据过快,流控队列长度txqueuelen又不够大时,就容易出现丢包现象。

网卡丢包

网卡和它的驱动导致丢包的场景也比较常见,原因很多,比如网线质量差,接触不良

RingBuffer过小导致丢包

在接收数据时,会将数据暂存到RingBuffer接收缓冲区中,然后等着内核触发软中断慢慢收走。如果这个缓冲区过小,而这时候发送的数据又过快,就有可能发生溢出,此时也会产生丢包

RingBuffer增大之后,可以减少因为容量小而导致的丢包情况。

网卡性能不足

网卡作为硬件,传输速度是有上限的。当网络传输速度过大,达到网卡上限时,就会发生丢包。

接收缓冲区丢包

我们一般使用TCP socket进行网络编程的时候,内核都会分配一个发送缓冲区和一个接收缓冲区

发送数据包会在代码中执行send(msg),这时候把数据拷贝到内核发送缓冲区中,什么时候发数据发多少数据由内核自己决定。

接收数据包也是,从外部网络收到数据包就暂存在这个地方,然后坐等用户空间的应用程序将数据包取走。

对于发送缓冲区,执行send的时候,如果是阻塞调用,那就会等,等到缓冲区有空位可以发数据。

如果是非阻塞调用,就会立刻返回一个 EAGAIN 错误信息,意思是 Try again。让应用程序下次再重试。这种情况下一般不会发生丢包。

接受缓冲区满了,事情就不一样了,它的TCP接收窗口会变为0,也就是所谓的零窗口,并且会通过数据包里的win=0,告诉发送端,"球球了,顶不住了,别发了"。一般这种情况下,发送端就该停止发消息了,但如果这时候确实还有数据发来,就会发生丢包

两端之间的网络丢包

两端之间那么长的一条链路都属于外部网络,这中间有各种路由器和交换机还有光缆啥的,丢包也是很经常发生的。

这些丢包行为发生在中间链路的某些个机器上,我们当然是没权限去登录这些机器。但我们可以通过一些命令观察整个链路的连通情况。

ping命令查看丢包:

想知道你的机器到baidu服务器之间,有没有产生丢包行为。可以使用ping命令。

mtr命令:

可以查看到你的机器和目的机器之间的每个节点的丢包情况。

发生丢包了怎么办

TCP协议去做传输4.21 用了 TCP 协议,数据一定不会丢吗?_第2张图片

建立TCP连接的两端,发送端在发出数据后会等待接收端回复ack包,ack包的目的是为了告诉对方自己确实收到了数据,但如果中间链路层发生了丢包,那发送端会迟迟收不到确认ack,于是就会进行重传。以此来保证每个数据包都确确实实到达了接收端。 

用了TCP协议就一定不会丢包吗4.21 用了 TCP 协议,数据一定不会丢吗?_第3张图片

 TCP位于传输层,上面应用层还有HTTP和RPC协议,TCP保证的可靠性是传输层的可靠性,它可以保证数据从A机器的传输层可靠的发到机器B的传输层。

数据到了接收端的传输层之后,能不能保证到应用层,TCP并不管。

聊天软件还需要将数据从TCP的接收缓冲区里读出来,如果在读出来这一刻,手机由于内存不足或其他各种原因,导致软件崩溃闪退了。

发送端以为自己发的消息已经发给对方了,但接收端却并没有收到这条消息。

于是乎,消息就丢了。

这类丢包问题怎么解决?

TCP只保证传输层的消息可靠性,并不保证应用层的消息可靠性。如果我们还想保证应用层的消息可靠性,就需要应用层自己去实现逻辑做保证。4.21 用了 TCP 协议,数据一定不会丢吗?_第4张图片

4.21 用了 TCP 协议,数据一定不会丢吗?_第5张图片

 

你可能感兴趣的:(小林coding,计算机网络,tcp/ip,网络,服务器)