大纲
- 建立连接时候丢包
- 流量控制丢包
- 网卡丢包
- RingBuffer过小导致丢包
- 网卡性能不足
- 接收缓冲区丢包
- 两端之间的网络丢包
建立连接时候丢包
Tcp协议通过三次握手建立连接。在服务端第一次握手后会先建立半连接
,而此时就会产生一个叫做半连接队列
的地方暂存数据。当接收到第三次握手后把链接队列就升级为全连接队列
暂存数据,等accept()方法将其取走。
是队列就有长度,有长度就有可能会满,如果它们满了,那新来的包就会被丢弃。
流量控制丢包
网卡丢包
RingBuffer过小导致丢包
在接收数据时,会将数据暂存到RingBuffer接收缓冲区中,然后等着内核触发软中断慢慢收走。如果这个缓冲区过小,而这时候发送的数据又过快,就有可能发生溢出,此时也会产生丢包。
网卡性能不足
网卡作为硬件,传输速度是有上限的。当网络传输速度过大,达到网卡上限时,就会发生丢包。
接收缓冲区丢包
使用TCP socket进行网络编程的时候,内核都会分配一个发送缓冲区和一个接收缓冲区。
当我们想要发一个数据包,会在代码里执行send(msg),这时候数据包并不是一把梭直接就走网卡飞出去的。而是将数据拷贝到内核发送缓冲区。而接收缓冲区作用也类似,从外部网络收到的数据包就暂存在这个地方,然后坐等用户空间的应用程序将数据包取走。
当接受缓冲区满了,它的TCP接收窗口会变为0,也就是所谓的零窗口,并且会通过数据包里的win=0,告诉发送端。一般这种情况下,发送端就该停止发消息了,但如果这时候确实还有数据发来,就会发生丢包。
两端之间的网络丢包