lwip-rawapi移植过程中,关于ping数据包 发送缓冲区大小问题的 探究。
为何不同路径/地区的用户在ping同一域名(ip地址可能不通)时,路径MTU值不同?
ping www.baidu.com -l [size--发送缓冲区大小]
一般来讲,最大传输单元MTU==1500。当然,这只是标准规则而已,总有些设备,他不在三界之内。。
当前测试:size<=996字节能通,
ping www.baidu.com -l 997 就已然不通啦...
而从网友那块得到了另一个路径MTU值,达到1472字节。。。。不得不查查相关概念啦。
路径MTU:
在因特网协议中,一条因特网传输路径的“路径最大传输单元”被定义为从源地址到目的地址所经过“路径”上的所有IP跳的最大传输单元的最小值。或者从另外一个角度来看,就是无需进一步分片就能穿过这条“路径”的传输单元的最大值。
在查找mtu==1500相关原由时,看到这样的一 ”问题---解释“,留存..
为什么以太网无法接收大于1500(大约、)字节的数据包?
对于选择帧的负荷量为1500字节,很明显有他的理由的。一个1500字节的帧,具有有最大的发送和接受效率。
As you know, ethernet frame has 8 byte preamble, 6 byte source and 6 byte destination mac address, mac type of 2 bytes, and 4 bytes CRC. Assuming the MTU payload to be 1500 the total number of bytes comes to 1500 + 8 + 6 + 6 + 2 + 4 = 1526 bytes. Now between each frame there is a inter frame gap of 12 bytes which constitues 9.6micro seconds gap between each frame. This is essential so that frames dont mix up. So the total size of each frame going out of a host is 1538 bytes.
如你所知,以太网帧有8个字节报头,6字节的源和6字节的目的MAC地址,MAC类型2个字节,4字节CRC。假设MTU的有效载荷是1500字节,则总的字节数1500+ 8 +6+6+ 2 + 4=1526字节。现在每帧之间有一个跨12字节的帧间隙(在每个字节中有9.6micro秒?没翻译过来,大致就是两个字节中有间隔)。这对于帧不混合到一起非常重要。因此,主机发出的每一帧的总大小为1538个字节
So at 10 Mbps rate, the frame rate is 10 Mbps / 1538 bytes = 812.74 frames / second.
因此,以10 Mbps的速率,帧速率是10Mbps/1538字节=812.74帧/秒。
Now we can find the throughput or efficiency of link, to transmit 1500 bytes of payload. by multiplying the frame rate with the number of bytes of the payload.
现在我们能够得到链路传输1500字节的吞吐量效率,通过使用帧速率和字节数的乘积。
So efficiency = 812.74 * 1500 * 8 = 9752925.xxxxx bps which is 97.5 percent efficient ( comparing with 10 MBps)
所以效率=812.74* 1500 *8=9752925. xxxxx bps效率97.5%(10 MBPS)
I guess I have gone too much with mathematics of Ethernet, but the interesting thing to notice is that, as the number of bytes in the payload increases, the frame rate is decreasing. See that for an MTU of 1500 bytes on payload, the frame rate has reduced to 812 frames per second. If you increase it above 1500, frame rate would become less than 812.
我想我说了太多关于因特网的数学的内容,但是我们会发现一个有趣的事情,随着字节负载的增加,帧速率在降低。你已经看到MTU为1500字节的时候,帧速率已经下降到812帧/S。如果你将帧增加超过1500字节,帧速率会小于812帧/S。
Also there is a minimum limit for the MTU which is actually 46 bytes. If you calculate the size of the frame for a 46 byte payload it would come to 12+8+6+6+2+46+4 = 84 bytes. Now calculating the frame rate we get it as =
10mbps/ (84 * 8 bytes) = 14880 frames per second. We could have gone to a frame size even lesser than this, which could increase the frame rate even more, but I guess during those times, when IEEE made the standards, the routers didnt have that much frame forwarding capability.
当然也有最小的MTU的值,是46字节。如果你计算46字节负载的时候,总字节为12+8+6+6+2+46+4 = 84字节,现在计算一下帧速率,我们得到10mbps/ (84 * 8 bytes) = 14880帧/S,它能够提升帧速率或者增加的更多,但是我想在IEEE定制标准的时候,路由器还没有那么强大的转发帧的能力。
So I think due to above reasons, and considering maximum efficiency, IEEE would have fixed the min and max size of payload as 46 bytes and 1500 bytes.
所以,我想基于以上的云因,考虑最大的效率,IEEE修订了最小和最大的字节传输量为46字节和1500字节。
手头上移植的一个lwip rawapi 网络协议栈,实测ping最大的数据包为1454byte,需要个理由。。。
关于lwip最大接收/发送 数据字节数的设置:
调试结果如下:
先看下下边的宏定义:
// The RXSTART_INIT should be zero. See Rev. B4 Silicon Errata
// buffer boundaries applied to internal 8K ram
// the entire available packet buffer space is allocated
//
// start with recbuf at 0/
#define RXSTART_INIT 0x0
// receive buffer end
#define RXSTOP_INIT (0x1FFF-0x0600-1)//接收缓冲区大小==0x19FE==6654字节
// start TX buffer at 0x1FFF-0x0600, pace for one full ethernet frame (~1500 bytes)
#define TXSTART_INIT (0x1FFF-0x0600)//发送缓冲区大小:==0x0600==1536字节
// stp TX buffer at end of mem
#define TXSTOP_INIT 0x1FFF
//
// max frame length which the conroller will accept:
#define MAX_FRAMELEN 1500 // (note: maximum ethernet frame length would be 1518)
//#define MAX_FRAMELEN 600
在补加上一组数据:
//定义发送接受缓冲区
u8 lwip_buf[1518 - 4];
以及相关的sizeof(lwip_buf)作为参数的一些条件判断,如驱动程序中的:enc28j60PacketReceive的参数
再就是:opt.h文件中的mtu正则匹配到的一些宏定义,但一般不会在lwipopts.h中更改,至少我这里没设置相关宏
解释:1、发送缓冲器设置-----接收、发送缓冲区的边界,当前设置的发送缓冲区相对小些,约1536字节;发送缓冲区,足够。。。
2、MAX_FRAMELEN 值,表示允许网卡接收/发送的最大帧长度,此处设置为1500字节,就是导致看到现象的原因。1454+8+20+14+CRC32=1500字节,再大就拒绝接收咯
3、再者便是:lwip_buf的设置,综合考虑,酌情取值,,,网卡中读到一帧的数据,放入lwip_buf中,该值小了可不好。。
更改
#define MAX_FRAMELEN 1518
与网卡驱动初始化函数中的实际配置:
enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF);
enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8);
详情参见:
《ENC28J60_cn.pdf》
《enc28j60勘误表.pdf》