龙空技术网

渔夫讲堂之二 UDP报文有多长?

渔夫评论 102

前言:

而今你们对“ethernet standard”大概比较看重,各位老铁们都需要学习一些“ethernet standard”的相关内容。那么小编在网上收集了一些对于“ethernet standard””的相关内容,希望看官们能喜欢,大家快快来了解一下吧!

渔夫讲堂不是字面上的那个意思,Peter’s Footprints也不是渔夫的脚印。这个系列的文章差不多都算作渔夫对于某些经验性内容的感悟,加上渔夫已经进入退休模式,渔夫希望这些小文能够让有缘者感悟到某些共鸣

很多年纪大的人说话会变得难懂,其中一个原因是如果懂得事情较多,又想把这些事情概括起来告诉读者,表达起来就晦涩起来。渔夫在写这些文字时会尽可能探讨简练的表达方式。

平时写程序并没有特别的讲究,对于UDP报文的长度也就凭印象定义了1500字节。人到老了,想法也会变化,想写一组C++的类库留下来。这些类库的写法出发点是完全的学术性与实用性的,希望为更多的程序员所利用,渔夫也会始终贯彻这个理念。

这种理念带来的变化是几乎每个细节都要特别的讲究,比方怎么定义UDP报文的长度?1500字节精确吗?

传统的Ethernet也就是以太网报文的格式是上面这个样子。渔夫在念研究院时,学的Ethernet还是DIX规范的同轴电缆做介质。

插一点历史,其实也是在写这个小文时现学的。Robert Metcalfe被认为是以太网之父,他在1973年5月22日写给上司(施乐Xerox公司的PARC研究中心)的便笺中第一次使用了Ethernet这个词,呵呵,那一年渔夫10岁。在此之前,夏威夷大学的ALOHA是用无线电作为通道,而Metcalfe则决定采用同轴电缆。1975年拿到了美国专利,1976年才发表了文章:Ethernet: Distributed Packet-Switching for Local Computer Networks。这一代的以太网原型传输速率大约在3Mbps,报文长度在500字节(或者以上)有95%以上的传输成功率。1980年有了open Ethernet standard。所谓open就不止一家供应商,DEC和Intel的加入就有了DIX规范, 叫做Ethernet2。网速达到了10Mbps。DIX规范的报文格式就是上面那个样子。在这里IP报文的最大长度1500字节。

DIX规范基础上的实现的IP报文的Ether Type为0x800,等于2048。而相关的ARP协议的Ether Type为0x806。

问题到这里还没完,1983年, Ethernet2演变成了IEEE 802.3,报文成了下面的样子:

IP报文的最大长度编程1492。但是,别担心,即便是现在,你在网上抓包看到的报文仍然是以Ethernet2为主,并不是因为大家不求进步,而是进步了技术,网络交换机为每个接口营造了一个单独的氛围。

渔夫也是当了很多年高校老师的人,渔夫讲课的风格就是本文这样,由简入繁。而且为了更好的理解繁,还有相应的铺垫。

无论是802.3还是DIX,Preamble/Start/FCS都是软件访问不到的位置,这些都是硬件自动产生的。Destination Address / Source Address这两个域软件需要设置,但是硬件会利用这些域做一些动作。比如Destination Address域在DIX规范时就开始解决单播/多播问题。

802.3就有了更多软件与硬件协同的域:Length/DSAP/SSAP/Control/Org code。802.3中的et就是DIX的Ether Type。有些三层IP交换机硬件还会直接根据IP datagram的某些域做出动作。

DIX与802.3良好共处在于Ether Type。由于报文长度在1500,而DIX在这个位置发送的是2048(Ether Type=IP),很容易被识别到。渔夫还想自己写一个协议,看来要把Ether Type设为0x900?

现在看看IP datagram内部:

最短的IP数据报头是20个字节。而UDP是IP的数据部分:

UDP也有头:

这样算起来,合理的UDP数据长度最大值为:1450-20-8=1422。接收缓冲区应该按这个值设置,但是要发送最好要更短一些,例如再减8个字节,以适应802.3。

渔夫讲课不敲黑板,不说重点,把渔夫朴实无华的话都理解了,一准行。

拓展开一点,就是软件能看到的网络报文。前面讲过,以太网的帧有些内容是软件看不见,有些是软件与硬件共同看见共同努力的。继续说就是,有些域是硬件能看见但不屑于处理的,其实硬件能看见所有的内容。

那么在Socket环境下能看到啥。注意渔夫的回到技巧:

在socket环境下,如果socket规约设定为AF_INET,这句话说的是IPV6等其它的就另当别论啦;如果是类型是SOCK_DGRAM,那么你只能用recvfrom函数,获得的数据是指向上图的 UDP Data,长度来自于UDP Header的Length,返回的远方端口来自UDP Header的Source Port,而远方的IP地址则来源于IP头部的Source Address。大概能知道的就这么多。

留个微信账号:18653652203。

标签: #ethernet standard