用了TCP协议就一定不会丢包吗( 四 )


# cat /proc/versionLinux version 3.10.0-1127.19.1.el7.x86_64
两端之间的网络丢包
前面提到的是两端机器内部的网络丢包,除此之外,两端之间那么长的一条链路都属于外部网络,这中间有各种路由器和交换机还有光缆啥的,丢包也是很经常发生的 。
这些丢包行为发生在中间链路的某些个机器上,我们当然是没权限去登录这些机器 。但我们可以通过一些命令观察整个链路的连通情况 。
ping命令查看丢包
比如我们知道目的地的域名是。想知道你的机器到baidu服务器之间,有没有产生丢包行为 。可以使用ping命令 。
?
ping查看丢包
倒数第二行里有个100%loss,意思是丢包率100% 。
但这样其实你只能知道你的机器和目的机器之间有没有丢包 。
那如果你想知道你和目的机器之间的这条链路,哪个节点丢包了,有没有办法呢?
有 。
mtr命令
mtr命令可以查看到你的机器和目的机器之间的每个节点的丢包情况 。
像下面这样执行命令 。
?
其中-r是指,以报告的形式打印结果 。
可以看到Host那一列,出现的都是链路中间每一跳的机器,Loss的那一列就是指这一跳对应的丢包率 。
需要注意的是,中间有一些是host是???,那个是因为mtr默认用的是ICMP包,有些节点限制了ICMP包,导致不能正常展示 。
我们可以在mtr命令里加个-u,也就是使用udp包,就能看到部分???对应的IP 。
?
mtr-udp
把ICMP包和UDP包的结果拼在一起看,就是比较完整的链路图了 。
还有个小细节,Loss那一列,我们在icmp的场景下,关注最后一行,如果是0%,那不管前面loss是100%还是80%都无所谓,那些都是节点限制导致的虚报 。
但如果最后一行是20%,再往前几行都是20%左右,那说明丢包就是从最接近的那一行开始产生的,长时间是这样,那很可能这一跳出了点问题 。如果是公司内网的话,你可以带着这条线索去找对应的网络同事 。如果是外网的话,那耐心点等等吧,别人家的开发会比你更着急 。
?
发生丢包了怎么办
说了这么多 。只是想告诉大家,丢包是很常见的,几乎不可避免的一件事情 。
但问题来了,发生丢包了怎么办?
这个好办,用TCP协议去做传输 。
?
TCP是什么
建立了TCP连接的两端,发送端在发出数据后会等待接收端回复ack包,ack包的目的是为了告诉对方自己确实收到了数据,但如果中间链路发生了丢包,那发送端会迟迟收不到确认ack,于是就会进行重传 。以此来保证每个数据包都确确实实到达了接收端 。
假设现在网断了,我们还用聊天软件发消息,聊天软件会使用TCP不断尝试重传数据,如果重传期间网络恢复了,那数据就能正常发过去 。但如果多次重试直到超时都还是失败,这时候你将收获一个红色感叹号 。
?
这时候问题又来了 。
假设某绿皮聊天软件用的就是TCP协议 。
那文章开头提到的女生,她男朋友回她的消息时为什么还会丢包?毕竟丢包了会重试,重试失败了还会出现红色感叹号 。
于是乎,问题就变成了,用了TCP协议,就一定不会丢包吗?
用了TCP协议就一定不会丢包吗
我们知道TCP位于传输层,在它的上面还有各种应用层协议,比如常见的HTTP或者各类RPC协议 。
?
四层网络协议
TCP保证的可靠性,是传输层的可靠性 。也就是说,TCP只保证数据从A机器的传输层可靠地发到B机器的传输层 。
至于数据到了接收端的传输层之后,能不能保证到应用层,TCP并不管 。