下表描述了整个从上到下的网络协议层:

这些网络协议在FPGA实际开发的过程中用到的就是传输层、网络层、数据链路层和物理层,在我们的举例中用到UDP、IP、ARP协议,物理层就用88E1111(10/100/1000BASE-T IEEE 802.3 compliant )的RGMII接口。
整个UDP报文层次结构如下图,请记住这张图贯穿整篇文章,层与层之间的关系搞不清楚了就回头来看看这张图,让自己的思路清醒一下。
好了,那么首先我们就从传输层开始,来一层一层的揭开UDP通信协议的面纱:
1、16位源、目的端口号:
源端口号:发送方发送数据的端口。
目的端口号:接收方接收数据的端口。
2、16位UDP长度 :
长度为16bit。UDP的长度是指包括包头和数据部分在内的总字节数。因为报头的长度是固定的,所以该域主要被用来计算可变长度的数据部分(又称为数据负载)。数据报的最大长度根据操作环境的不同而各异。理论上,包含报头在内的数据报的最大长度为65535字节,实际上,UDP的MTU一般为1500,这与CDMA/CS机制有关系,即使巨型包也不会超过65535,在基于USO和UFO层次时,可对UDP进行拆包处理。(这部分暂未研究,以后有机会一定要好好学习一哈)
3、16位UDP校验和:
占16bit,用来对UDP头部和UDP数据进行校验。UDP的校验和需要计算UDP首部+数据部分,但也需要加上UDP伪首部,这个伪首部指的是:
UDP校验和计算步骤如下:(注意啊,加上UDP伪首部,16位的UDP长度参与了两次运算)
(1)把校验和字段置为0;
(2)把需校验的数据看成以16位为单位的数字组成,依次进行二进制反码求和;
什么是二进制反码求和?答:对一个无符号的数,先求其反码,然后从低位到高位,按位相加,有溢出则向高位进1(跟一般的二进制加法规则一样),若最高位有进位,则向最低位进1。
翻译一下:把所有16位的字相加,如果遇到进位,则将高于16字节的进位部分的值加到最低位上,(即高位溢出位会加到低位),将得到的和的反码填入校验和字段。举例,0xBB5E+0xFCED=0x1 B84B,则将1放到最低位,得到结果是0xB84C。将所有字相加得到的结果应该为一个16位的数,将该数取反,则可以得到检验和checksum)
(3)把得到的结果存入校验和字段中。
另外UDP、TCP数据报的长度可以为奇数字节,如果在计算校验和数据长度不能满足16bit的整倍数,需要填充一个字节的0。(注意,填充字节只是为了计算校验和,可以不被传送)。
4、数据
打包在UDP协议中的用户数据。
前20字节为IP数据报的首部,IP数据报的首部是固定的,首部的每一行是一个32位的单位,最高位在左边,为0bit,最低位在右边,为31bit。
4字节的32bit数据传输次序为:首先0~7bit,其次8~15bit,然后16~23bit,最后是24~31bit,这种传输次序为big endian(大端对齐)。TCP/IP所有二进制整数在网络中传输时都要求采用这种次序,因此这种传输次序又称为网络字节序。
1、版本+首部长度:
长度为1字节。
版本[0:3]:就是IPv4或者IPv6,一般选择IPv4,即版本值为4。
首部长度[4:7]:是指首部有多少个32位数,因为4位的最大值为15,因此首部最长为60字节,5表示固定最小值为20字节。选项部分(可选字段)的最大值为40字节,不够4的倍数要用0填充,使数据部分的起始地址为4的倍数。
2、服务类型 :
长度为8比特,置0。
3、总长度 :
长度为2Byte。总长度是指整个IP数据报的长度(IP报头+数据),16bit,最长为65535字节,如果超过1500-20=1480还需要进行分包处理。
4、分段标识:
长度为2Byte。是否属于同一数据段,IP报文的分段ID。随意置数即可。
5、段标识和段偏移:
长度为2B。置0即可。
6、生成周期(TTL):
长度为1Byte。
表示这可经过的最大路由数,生存时间字段设了数据包可以经过的最大路由数,表示数据包在网络上生存多久。TTL的初始值由源主机设置(通常为32或64),一旦经过一个路由器(网络层),他的值就减去1,当该字段的值为0时,数据报就被丢弃,并发送ICMP消息通知源主机,这样当封包在传递过程中由于某些原因未能抵达目的地的时候就可以避免其一直充斥在网路。
7、上层协议(上层为传输层):
1Byte。指示该封包所使用的网络协议类型,常用的协议号:
16’d00:IP
16’d01:ICMP
16’d06:TCP
16’d17:UDP
8、报头校验和:
2Byte。
IP报头的校验和,只校验IP报头,不对首部后面数据进行计算,计算方法和UDP校验和计算方法一样:
(1)将校验和字段置0,然后将IP包头按照16bit分成更多单元,如包头长度不是16bit整数倍,则用0bit填充到16bit的倍数。
(2)对各个单元采用反码加法运算(即高位溢出位会加到低位),将得到的和的反码填入校验和字段。
9、源IP地址:
4byte。发送端的IP地址。
10、目的IP地址 :
4Byte。接收端的IP地址。
11、可选字段:
可选,没有时候可以为0,最大为40字节,必须为4的倍数,不到的话用0填充。
MAC帧是数据帧的一种,所谓数据帧,就是数据链路层的协议数据单元,包括三部分:帧头、数据部分、帧尾。其中,帧头和帧尾包含一些必要的控制信息,比如同步信息、地址信息、差错控制信息等;数据部分则包含网络层传输下来的数据,比如IP数据包。
前导码和帧起始符不算MAC帧组成,所以MAC帧的固定长度为6+6+2+4=18。
MAC帧的帧头包括三个字段,前两个字段分别为6字节长的目的地址字段和源地址字段,第三个字段为2字节的类型/长度字段。
1、前导码(Preamble):
不算在MAC帧成分,前导码的作用是使主机接收器时钟和源主机发送器时钟同步,紧接着是帧开始分界符字节0x55或者0xAA,用于指示帧的开始,前导码是为了隔离每个以太网帧的,也是定位符。因为以太网是变长的,所以每个帧之间需要前导码来确认。字段长度为:7个字节。
2、帧开始符(SFD)
不算MAC帧成分,8’hd5:表明下一字段为为目的MAC字段。
3、目的MAC地址:
长度为:6个字节,指接收方。广播时为(ff_ff_ff_ff_ff_ff) ,例如ARP请求包发送时。
4、源MAC地址:
长度为6个字节,指发送者。
5、长度/类型(type/length):
帧的数据字段长度,为2个字节,type/length规定大于0x600就是type帧,小于或等于1500则指示帧的有效数据长度,length标识有效载荷的数据长度,不包含填充的长度。当类型字段的数值为0x0800时,就表示使用的是IP报文。当类型字段的数值为0x0806时,就表示使用的是ARP报文。
6、数据和填充(数据部分)
Data and Pad,长度为46~1500,包含的是高层(网络层)的数据,通常是3层协议单元,对于TCP/IP是IP数据包。
(46B如何得出?)
以太网最小帧长64B。去掉MAC帧18B的首部地址和尾部,64-18=46。如果一个帧的数据部分少于46B,则MAC子层就会在就会在有效数据字段的后面加入填充字段Pad,以保证以太网的MAC地址不低于64B。再计算一下,去掉IP报头20B,去掉UDP报头8B,实际我们要发送的数据最小为46-20-8=18B,但是我们为什么还能发一个字节或者两个字节呢?其实就是被Pad字段填充补齐了一帧数据。
MAC帧中数据和填充部分的长度必须在46~1500字节之间,这是由以太网的物理特性决定的,这个1500字节被称为链路层的MTU(最大传输单元,Max Transmit Unit),但是这并不是指链路层的长度被限制在1500字节,MTU指的是链路层的数据区,并不包括链路层的首部和尾部的18字节。
因为IP数据报的首部长度为20字节,所以IP数据报的数据区长度为1480字节,而这个1480字节就是用来存放TCP传来的TCP报文段或者UDP传来的UDP数据报的,又因为UDP数据报的首部为8字节,所以UDP数据报的数据区最大长度为1472字节。(这1472即为可使用的字节数)
在普通局域网环境下,将UDP的数据控制在1472字节下最好。在intel上标准MTU的值为576字节,一般就是512字节一个包,大数据使用分包—封包处理。
7、帧校验序列(FCS)
使用CRC循环冗余校验码校验,判断是否传输错误,如果发现错误,丢弃此帧。这个字段只是提供检错功能,并不提供纠错功能,该校验范围为:目的地址+源地址+类型/长度+数据字段。
CRC循环冗余校验码校验:循环冗余校验同其他差错检测方式一样,通过在要传输的k比特数据D后添加(n-k)比特冗余位(又称帧检验序列,Frame Check Sequence,FCS)F形成n比特的传输帧T,再将其发送出去。
下面以最常用的CRC-16为例来说明其生成过程。
CRC-16码由两个字节构成,在开始时CRC寄存器的每一位都预置为1,然后把CRC寄存器与8-bit的数据进行异或,之后对CRC寄存器从高到低进行移位,在最高位(MSB)的位置补零,而最低位(LSB,移位后已经被移出CRC寄存器)如果为1,则把寄存器与预定义的多项式码进行异或,否则如果LSB为零,则无需进行异或。重复上述的由高至低的移位8次,第一个8-bit数据处理完毕,用此时CRC寄存器的值与下一个8-bit数据异或并进行如前一个数据似的8次移位。所有的字符处理完成后CRC寄存器内的值即为最终的CRC值。
1.设置CRC寄存器,并给其赋值FFFF(hex)。
2.将数据的第一个8-bit字符与16位CRC寄存器的低8位进行异或,并把结果存入CRC寄存器。
3.CRC寄存器向右移一位,MSB补零,移出并检查LSB。
4.如果LSB为0,重复第三步;若LSB为1,CRC寄存器与多项式码相异或。
注意:该步检查LSB应该是右移前的LSB,即第3步前的LSB。
5.重复第3与第4步直到8次移位全部完成。此时一个8-bit数据处理完毕。
6.重复第2至第5步直到所有数据全部处理完成。
7.最终CRC寄存器的内容即为CRC值。
上面我们已经一层层的将UDP的数据包讲解完毕,下面就要把UDP通信的整个过程来梳理一下,让大家对UDP通信的过程有一个整体的认知:
1、主机、从机设定好MAC地址、IP地址、端口号。
2、主机广播从机IP地址,发送ARP请求,寻找从机MAC地址。
3、从机接收到主机的ARP请求,产生应答,把本地的MAC地址发送给主机。
4、主机接收到ARP应答后,主从就建立起了网络连接,可以互相发送UDP数据报。
这四个步骤就是两台设备间简单的UDP通信过程,其中我们提到了ARP,那么ARP具体是什么呢?
在网络访问层中,同一局域网中的一台主机要和另一台主机进行通信,需要通过 MAC 地址进行定位,然后才能进行数据包的发送。而在网络层和传输层中,计算机之间是通过 IP 地址定位目标主机,对应的数据报文只包含目标主机的 IP 地址,而没有 MAC 地址。因此,在发送之前需要根据 IP 地址获取 MAC 地址,然后才能将数据包发送到正确的目标主机,而这个获取过程是通过 ARP 协议完成的。
1、ARP 工作的基本流程:
ARP 工作流程分为两个阶段,一个是 ARP 请求过程,另一个是 ARP 响应过程。
工作流程如下所示。


在上面图片中,主机 A 的 IP 地址为 192.168.1.1,主机 B 的 IP 地址为 192.168.1.2。
主机 A 与主机 B 进行通信,需要获取其 MAC 地址,基本流程如下:
2、ARP报文格式:
ARP 协议是通过报文进行工作的,ARP 报文格式如图所示。

ARP 报文总长度为 28 字节,MAC 地址长度为 6 字节,IP 地址长度为 4 字节。
其中,每个字段的含义如下。
ARP 数据包分为请求包和响应包,对应报文中的某些字段值也有所不同。


RGMII数据接口采用DDR双沿采样,4bit位宽,上升沿采低4bit,下降沿采高4bit,一个周期的期拼成一个字节。

介绍到这就可以了,UDP数据包按照88E1111接口时序发送出去就好了,其实最主要的还是搞懂UDP数据包,88E1111就是一个收发数据的物理接口。
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
在Rails中,什么是集成更新模型某些元素的UDP监听过程的最佳方式(特别是它将向其中一个表添加行)。简单的答案似乎是在同一个进程中使用UDP套接字对象启动一个线程,但我什至不清楚我应该在哪里做适合Rails方式的事情。有没有一种巧妙的方法来开始收听UDP?具体来说,我希望能够编写一个UDPController并在每个数据报消息上调用一个特定的方法。理想情况下,我希望避免在UDP上使用HTTP(因为它会浪费一些在这种情况下非常宝贵的空间),但我完全控制消息格式,因此我可以为Rails提供它需要的任何信息。 最佳答案 Rails是一个
我一直在为使用acts_as_list的模型实现一些不错的交互界面,这些界面可以对我的mRails应用程序中的列表进行排序。我有一个排序函数,在每次拖放之后使用sortable_elementscript.aculo.us函数调用并设置每条记录的位置。这是在拖放完成后处理排序的Controller操作示例:defsortparams[:documents].each_with_indexdo|id,index|Document.update_all(['position=?',index+1],['id=?',id])endend现在我正在尝试对嵌套集模型(acts_as_nested
最近在工作中,看到一些新手测试同学,对接口测试存在很多疑问,甚至包括一些从事软件测试3,5年的同学,在聊到接口时,也是一知半解;今天借着这个机会,对接口测试做个实战教学,顺便总结一下经验,分享给大家。计划拆分成4个模块跟大家做一个分享,(接口测试、接口基础知识、接口自动化、接口进阶)感兴趣的小伙伴记得关注,希望对你的日常工作和求职面试,带来一些帮助。注:文章较长有5000多字,希望小伙伴们认真看完,当然有些内容对小白同学不是太友好,如果你需要详细了解其中的一些概念或者名词,请在文章之后留言,后续我将针对大家的疑问,整理输出一些大家感兴趣的文章。随着开发模式的迭代更新,前后端分离已不是新的概念,
功能需求:主机使用一个串口,与两个从机进行双向通信,主机向从机发送数据,从机能够返回数据,由于结构限制,主机与从机之间只有3根线(电源、地、数据线),并且从机上没有设物理的电源开关,需要通过与主机连接的数据线来控制开机,总结如下:1、数据线只有1根2、能够双向通信3、主机能够控制从机开机4、主机可以单独向1个从机发数据,也可以同时向两个从机发送数据根据需求,设计出如下电路:工作原理分析:VCC_24V_IN、GND、LINE_L(LINE_R)三根线接线连接到从机,电源开启电路是从机内部的电源控制。开机的逻辑:*主机先上电,LINE_L因为主机的R1上拉而有高电平,使Q6导通,Q5的G极电压被
我正在尝试在我的Rails应用程序中使用模型来从外部API检索信息。我想做的是以类似于ActiveRecord模型提供的方式(特别是关联,以及相同风格的可链接查询方法)访问我的数据模型(可能包含来自多个API调用的信息)。我最初的直觉是重新创建我想要的ActiveRecord部分并合并此API。不想“重新发明轮子”并确切地看到添加更多功能需要多少工作让我退后一步并重新评估如何处理这个问题。我找到了在没有表的情况下使用ActiveRecord的方法(请参阅:Railscast#193TablelessModel和博客文章here)并研究了ActiveRecord。因为ActiveMode
原文:UsetheIComparableandIComparerinterfacesinVisualCSharp本文介绍了在VisualC#中如何使用IComparer和IComparable接口。概要本文同时讨论了IComparable和IComparer接口,原因有两点。这两个接口经常一起使用。虽然接口类似且名称相似,但它们却有不同的用途。如果你有一个支持IComparer的类型数组(例如字符串或整数),你可以对它进行排序而不需要提供任何对IComparer的显式引用(译注:意思是把一个IComparer的实现类作为参数传递给排序方法)。在这种情况下,数组元素会被转换为IComparer的
我有一个RaspberryPiTFT7"触摸屏显示器,我想创建一个简单的应用程序来显示和输出系统数据(即CPU使用率、温度等)。我注意到目前常见的实现方法是使用pygame库输出到显示器连接到的帧缓冲区/dev/fb1。我想执行相同的操作,但使用Ruby,因为我更熟悉这门语言。有人可以为我指明正确的方向,让我知道如何开始吗?我查看了rubygame和gosu库,它们似乎能够做我想做的事情,即绘制屏幕,但我找不到任何关于如何将输出定向到的信息帧缓冲区本身。 最佳答案 rubycorelib有一个IO您应该能够使用该类将输出定向