stm32读取数据包 已知一个一个硬件stm32的通信协议议,用什么方法把这个硬件的数据提取出来,怎么样才

我写的一个实现单片机与PC机多机通讯的程序 串口通信 - 单片机/MCU论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
我写的一个实现单片机与PC机多机通讯的程序 串口通信
16:57:45  
15990&查看
& & 下面是我写的一个实现多个下位机(单片机)与一个上位机(PC机)的一主多从串口通讯程序,用的STC89C52RC,定时器2做串口通信波特率发生器。
& &&&实现功能是这样的:
& &&&用调试助手向单片机发送一个数据包。
& &&&通讯协议是这样的:
& && &数据包的格式如下所示(共10个字节组成):
0x2A,0xEB,0x8D,地址码,指令码,数据长度码,数据码,数据码,校验码,0xAD&&
前面三个字节为帧头,即开始符。
地址码: 欲传送的目的地址,即选定哪一个单片机。
指令码:向单片机发送的指令
数据长度码: 用于指示后面有效数据的个数
数据码:传送的数据,配合指令码的纯数据。
校验码: 累加和校验,对地址码,指令码,数据长度码,数据码进行累加,用来检验数据的完整性和正确性。
0xAD : 帧尾,即结束符。
& & 本程序实现功能是这样的:
& & 用调试助手向单片机发送一个数据包,单片机收到后对数据解析,再回传指定的数据。
& & 例如发送:2a eb 8d 01 03 01 01 06 ad
指令码为01,单片机接收到后解析,回传0xce 0x7b 0x11 0xed。其中前两个字节为开始符,最后一个字节为结束符。同理,若收到的指令码为02,回传0xce 0x7b 0x12 0xed。以此模拟控制单片机操作。
若接收错误,即累加校验码不等于单片机实际计算的累加和,回传0xce 0x7b 0x02 0xed,提示接收错误,要求PC重发数据(模拟,需要上位机软件配合才行)。
单片机开机初始化后即向PC发送一个数据0xce 0x7b 0x00 0xed,用于指示单片机与PC通信已连接。
下面是程序:
#define ID 0x01 //单片机地址
uint8 rec_& &//串口通信接收数据
uint8 state_flag=0;&&//通信协议解析状态标志,初始化为0
uint8 retval=0;&&//通信协议解析函数返回值,初始化为0
uint8&&//指令码
uint8 Data[2];&&//数据码
uint8 data_&&//数据长度码
程序大体思想是:
& & 首先定义了几个全局变量,接收到数据后,串口中断子程序中用变量rec_data存储一个字节的数据,随后对数据进行解析:首先判断数据包的完整性,正确性,然后提取指令码,数据码等数据,存放起来用于主程序处理。
& & 协议解析过程中,使用一个变量state_flag的全局变量作为协议解析状态标志,用于确定当前字节处于一帧数据中的那个部位,同时在接收过程中自动对接收数据进行校验和处理,在数据包接收完的同时也进行了校验的比较。因此当帧尾结束符接收到的时候,则表示一帧数据已经接收完毕,并且也通过了校验,关键数据也保存到了缓冲区(cmd和Data[])中。主程序即可通过查询retval的标志位来进行协议的解析处理。如果retval=1;& &//错误标志,数据包传送不正确。如果retval=2;& &//接收成功标志,数据包传送成功。
& & 接收过程中,只要哪一步收到的数据不是预期值,则直接将状态标志复位,用于下一帧数据的判断,避免状态自锁。
& & 以下是程序:
void PortInit();& && && && && & //各端口初始化
void TimerInit();& && &&&//定时器初始化
void UsartInit();& && &&&//串口初始化
void usart_cmd_scan();& && &&&//串口命令扫描
void Data_analysis();& &//通信协议解析函数
void Send(uint8 sendcmd);&&//数据发送函数
/*--------------------------------& && &&&串口中断服务子程序 ------------------------------------*/
void ser() interrupt 4
& &rec_data=SBUF;& &//读取接收到的数据
& &Data_analysis();//数据解析&&
* 函数名:Data_analysis
* 描&&述:通信协议解析函数
* 输&&入:无
* 输&&出:无
* 备&&注:解析串口接收到的数据
/*--------------------------------& && &&&多机通信协议格式 ------------------------------------*/
/*&&数据包的格式如下所示(共10个字节组成): */
/*&&0x2A,0xEB,0x8D,地址码,指令码,数据长度码,数据码,数据码,校验码,0xAD&&*/
void Data_analysis()
& &static uchar recdata_sum=0;&&//存放累加和
& &static uchar lencnt=0;&&//数据长度计数器
& &switch (state_flag)
& && &&&case 0:
& && && & {
& && && && & if(rec_data == 0x2A)& &&&// 是否帧头第一个数据
& && && && && &state_flag = 1;
& && && && & else
& && && && && &state_flag = 0;& & // 标志复位
& && && && && && &
& && && & }
& && &&&case 1:
& && && & {
& && && && & if(rec_data == 0xEB)& &&&// 是否帧头第二个数据
& && && && && &state_flag = 2;
& && && && & else
& && && && && &state_flag = 0;& & // 标志复位
& && && && &
& && && & }
& && &&&case 2:
& && && & {
& && && && & if(rec_data == 0x8D)& &&&// 是否帧头第三个数据
& && && && && &state_flag = 3;
& && && && & else
& && && && && &state_flag = 0;& & // 标志复位
& && && && &
& && && & }
& && &&&case 3:
& && && & {
& && && && & if(rec_data == ID)& & // 判断目的地址是否正确
& && && && && &{
& && && && && && &state_flag = 4;
& && && && && && &recdata_sum=rec_& &//开始累加
& && && && && &}& &
& && && && & else
& && && && && &state_flag = 0;& &// 标志复位
& && && && &
& && && & }
& && &&&case 4:
& && && & {
& && && && & state_flag = 5;
& && && && & cmd=rec_&&//指令码存储
& && && && & recdata_sum+=rec_&&//累加
& && && && &
& && && & }& && &&&
& && &&&case 5:
& && && & {
& && && && & lencnt = 0;&&//数据长度计数器清零
& && && && & data_count=rec_&&//数据长度码存储
& && && && & recdata_sum+=rec_&&//累加
& && && && & if (data_count!=0)&&//后面有数据码
& && && && && &state_flag=6;
& && && && & else
& && && && && &state_flag=8;
& && && && &
& && && & }
& && &&&case 6:
& && &&&case 7:
& && && & {
& && && && &&&Data[lencnt++]=rec_&&//数据码保存
& && && && &&&recdata_sum+=rec_& &//累加
& && && && &&&if(lencnt==data_count)
& && && && &&&{
& && && && && && && && && && && && && && &state_flag=8;
& && && && && && && && && && && && && & lencnt = 0;& && &&&
& && && && && && && && &&&}&&
& && && && && && && && && && &&&
& && && && &&&else
& && && && && & state_flag=7;
& && && && &&&
& && && & }
& && &&&case 8:
& && && & {
& && && && & if(recdata_sum==rec_data)& &//数据校验,判断累加和是否相等
& && && && && &state_flag=9;
& && && && & else
& && && && && &{
& && && && && && &retval=1;& &//置错误标志,数据包传送不正确。
& && && && && && &state_flag=0;& &
& && && && && &}
& && && && && && && && & recdata_sum=0;//累加和清零
& && && && &
& && && & }
& && &&&case 9:
& && && & {
& && && && & if (rec_data==0xAD)
& && && && && &{
& && && && && && && && && && && && && && & retval=2;& &//置接收成功标志,数据包传送成功。
& && && && && && && && && && && && && & state_flag=0;
& && && && && && && && && &}
& && && && & else
& && && && && &state_flag=0;
& && && && &
& && && & }
//主程序 , 不断扫描串口接收到的命令
void main()
& && &&&PortInit();& && && && && & //各端口初始化
& && &&&TimerInit();& && &&&//定时器初始化
& && &&&UsartInit();& && &&&//串口初始化& && && && && && && && && && && &&&
& && &&&Send(0xce);
& && &&&Send(0x7b);
& && &&&Send(0x00);
& && &&&Send(0xed);
& && &&&while(1)
& && && && && & usart_cmd_scan();& && &&&//串口命令扫描
& && &&&}& && &&&
* 函数名:usart_cmd_scan
* 描&&述:串口命令扫描
* 输&&入:无
* 输&&出:无
* 备&&注:扫描PC通过串口发送的命令
void usart_cmd_scan()
& && &&&& &//下位机向PC发送的命令码
& && && &&&switch (retval)
& && &&&case 1:& && &//数据发送错误,请求PC重发
& && && & {
& && && && & sendcmd=2;&&//向PC发送的重发数据命令,PC识别后向下位机重发数据包。
& && && && & Send(0xce);
& && && && && && && && & Send(0x7b);
& && && && && && && && & Send(sendcmd);
& && && && && && && && & Send(0xed);&&//向PC发送命令
& && && && && && && && & retval=0;& &//标志清零,防止重复扫描,重复执行。&&
& && && && && && && && &
& && && & }
& && &&&case 2:& && &//数据发送成功,执行命令
& && && & {
& && && && & switch (cmd)& & //命令解码
& && && && && && && && & {
& && && && && && && && && && && &case 0x01:
& && && && && && && && && && &&&{
& && && && && && && && && && && && && & Send(0xce);
& && && && && && && && && && && && && & Send(0x7b);
& && && && && && && && && && && && && & Send(0x11);
& && && && && && && && && && && && && & Send(0xed);
& && && && && && && && && && && && && & cmd=0x00;
& && && && && && && && && && && && && &
& && && && && && && && && && &&&}
& && && && && && && && && && &&&case 0x02:
& && && && && && && && && && &&&{
& && && && && && && && && && && && && & Send(0xce);
& && && && && && && && && && && && && & Send(0x7b);
& && && && && && && && && && && && && & Send(0x12);
& && && && && && && && && && && && && & Send(0xed);
& && && && && && && && && && && && && & cmd=0x00;
& && && && && && && && && && && && && &
& && && && && && && && && && &&&}
& && && && && && && && && && &&&case 0x03:
& && && && && && && && && && &&&{
& && && && && && && && && && && && && & Send(0xce);
& && && && && && && && && && && && && & Send(0x7b);
& && && && && && && && && && && && && & Send(0x13);
& && && && && && && && && && && && && & Send(0xed);
& && && && && && && && && && && && && & cmd=0x00;
& && && && && && && && && && && && && &
& && && && && && && && && && &&&}& && && && && &&&
& && && && && && && && & }
& && && && &}
& && && && && && &retval=0;& &//标志清零,防止重复扫描,重复执行。
* 函数名:Send
* 描&&述:串口数据发送函数
* 输&&入:sendcmd - 待发送的数据
* 输&&出:无
* 备&&注:
void Send(uint8 sendcmd)
& &ES=0;&&//关闭串口
& &SBUF=&&//发送数据,向PC发送。
& &while(!TI);
& &TI=0;&&//发送完成,TI清零
& &ES=1;&&//开串口
以上是我写的这个程序,希望大家指点一下。
程序运行整体可以,但是有个问题,也希望大神们能帮忙看一下什么问题
每次在单片机关机后,再重新上电后,发送都没反应,只有手动按下开发板的复位键后才能正常通信,当再次断电上电后,又不行了,又得按复位键才正常。按说开发板上电就复位了呀,为什么还要手动复位才行?什么的问题?你们试一下这个程序有这个问题吗?
& & 还望大神们帮忙指点啊!
11:31:40  
贴一下具体的复位电路看看 是不是元件取值不合适 脉冲宽度不够
11:18:18  
PCB在线计价下单
板子大小:
板子数量:
PCB 在线计价
大哥,你这个可以实现pc对多个单片机吗?我的点对点可以,一对多就不可以,希望指点,谢谢!急啊!
高级工程师
08:33:53  
谢谢楼主分享好资料,先收藏了,方便学习交流,我正在收集这方面资料。
13:59:56  
楼主厉害了啊,我自己写一个点对点的,没成功,用的RS-485总线,我就是想不明白,请楼主指点指点
12:25:11  
好好看看。。。。。。。。。。。。。
13:46:54  
学习学习很不错的分享
20:02:54  
刚好用到这个,,谢谢楼主,好人灬灬灬灬灬灬灬灬灬灬灬灬
22:26:41  
学习学习很不错的分享
09:00:01  
好东西,刚好需要,学习一下
10:52:46  
我不会告诉你,如果知道了CAN就不用这么麻烦了,亦或者你看看MODBUS协议就知道了。
等待验证会员
06:34:32  
初始化之后延时再发送试试
18:28:06  
楼主很强啊,谢谢分享
23:42:00  
可以的,很棒
10:07:46  
复位电路可能有问题
11:36:13  
谢谢 分享!!!!!
13:38:46  
13:39:34  
等待验证会员
15:27:59  
LZ 我试了一下&&助手上没有显示单片机回复的数据啊
16:01:13  
Powered by
供应链服务
商务及广告合作
Jeffery Guo
关注我们的微信
供应链服务 PCB/IC/PCBA
下载发烧友APP
版权所有 (C) 深圳华强聚丰电子科技有限公司STM32系列 IIC 使用总结_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
STM32系列 IIC 使用总结
&&STM32 系列 IIC 通信资料
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩26页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢STM32再学习之工程师眼中的SPI
> STM32再学习之工程师眼中的SPI
STM32再学习之工程师眼中的SPI
  前些天,有位网友谈到通过来实现通讯。通过帖子的回复发现好多网友对通讯还有些疑惑,于是今天就带着大家从的标准协议,SPI在STM32单片机上的配置及在74HC595逻辑芯片通讯的实例来全方面认识一下这个既复杂又简单的通讯协议。本文引用地址:
  SPI 是Serial Peripheral Interface的缩写,直译为串行外围设备接口,SPI是Motorola公司推出的一种同步串行通讯方式,是一种四线同步总线,因其硬件功能很强,与SPI有关的软件就相当简单,使有更多的时间处理其他事务。这里要说明一下,专利在电子行业还是很关键的,因此,部分其它厂商将SPI通讯协议更名以规避高昂的专利费,但其硬件处理方式是一样的,只是换了一个名称而已,例如德仪单片机里的SSI通讯。
  常用的SPI通讯方式是标准四线制,如下图电路示意图所示:
  MISO:主设备输入/从设备输出引脚。该引脚在从模式下发送数据,在主模式下接收数据。
  MOSI:主设备输出/从设备输入引脚。该引脚在主模式下发送数据,在从模式下接收数据。
  SCK:串口时钟,作为主设备的输出,从设备的输入
  NSS:从设备选择。这是一个可选的引脚,用来选择主/从设备。
  MOSI脚相互连接,MISO脚相互连接。这样,数据在主和从之间串行地传输(MSB位在前)。通信总是由主设备发起。主设备通过MOSI脚把数据发送给从设备,从设备通过MISO引脚回传数据。这意味全双工通信的数据输出和数据输入是用同一个时钟信号同步的;时钟信号由主设备通过SCK脚提供。
  比较复杂的是这个从选择(NSS)脚。其有两种模式:软件NSS模式与硬件NSS模式。
  软件NSS模式下:在该模式下说得简单一些就是此引脚当作普通的GPIO来使用。其输入/输出的功能与操作GPIO是一样的。我们通过STM32来操作片外设备时多采用此模式。
  硬件NSS模式下:此模式又下分两种情况:情况一、NSS输出被使能:当STM32工作为主SPI,并且NSS输出已经使能,这时NSS引脚被拉低,所有NSS引脚与这个主SPI的NSS引脚相连并配置为硬件NSS的SPI设备,将自动变成从SPI设备;情况二、NSS输出被关闭:允许操作于多主环境。
  硬件的连接我们说完了,下面我再来介绍时钟线与信号线。
  在学习数字逻辑电路时,我们都听老师讲过数据的锁存方式,例如上升沿锁存等。我们的SPI通讯方式在硬件上非常灵活的处理数据锁存方式,通过两个参数的配置提供了四种不同的数据传输模式,如下图所示:
fpga相关文章:
数字通信相关文章:
分享给小伙伴们:
我来说两句……
最新技术贴
微信公众号二
微信公众号一网络数据包传输过程总结 - CSDN博客
网络数据包传输过程总结
一、数据包是如何在网络中传输的
我们电脑上的数据,是如何“走”到远端的另一台电脑的呢?这是个最基础的问题,可能很多人回答不上来,尽管我们每天都在使用网络。这里我们以一个最简单的“ping”命令,来解释一个数据包“旅程”。
&&&&假设:我的电脑A,向远在外地的朋友电脑B传输数据,最简单的就是“ping”一下,看看这个家伙的那一端网络通不通。A与B之间只有一台路由器。(路由器可能放在学校,社区或者电信机房,无所谓,基本原理是一样的)
具体过程如下------
&&&&1.“ping”命令所产生的数据包,我们归类为ICMP协议。说白了就是向目的地发送一个数据包,然后等待回应,如果回应正常则目的地的网络就是通的。当我们输入了“ping”命令之后,我们的机器(电脑A)就生成了一个包含ICMP协议域的数据包,姑且称之为“小德”吧~~~~
&&&&2.“小德”已经将ICMP协议打包到数据段里了,可是还不能发送,因为一个数据要想向外面传送,还得经过“有关部门”的批准------IP协议。IP要将你的“写信人地址”和“收信人地址”写到数据段上面,即:将数据的源IP地址和目的IP地址分别打包在“小德”的头部和尾部,这样一来,大家才知道你的数据是要送到哪里。
&&&&3.准备工作还没有完。接下来还有部门要审核------ARP。ARP属于数据链路层协议,主要负责把IP地址对应到硬件地址。直接说吧,都怪交换机太“傻”,不能根据IP地址直接找到相应的计算机,只能根据硬件地址来找。于是,交换机就经常保留一张IP地址与硬件地址的对应表以便其查找目的地。而ARP就是用来生成这张表的。比如:当“小德”被送到ARP手里之后,ARP就要在表里面查找,看看“小德”的IP地址与交换机的哪个端口对应,然后转发过去。如果没找到,则发一个广播给所有其他的交换机端口,问这是谁的IP地址,如果有人回答,就转发给它。
&&&&4.经过一番折腾,“小德”终于要走出这个倒霉的局域网了。可在此之前,它们还没忘给“小德”屁股后面盖个“戳”,说是什么CRC校验值,怕“小德”在旅行途中缺胳膊少腿,还得麻烦它们重新发送。。。。。我靠~~~~注:很多人弄不清FCS和CRC。所谓的CRC是一种校验方法,用来确保数据在传输过程中不会丢包,损坏等等,FCS是数据包(准确的说是frame)里的一个区域,用来存放CRC的计算结果的。到了目的地之后,目的计算机要检查FCS里的CRC值,如果与原来的相同,则说明数据在途中没有损坏。
&&&&5.在走出去之前,那些家伙最后折磨了一次“小德”------把小德身上众多的0和1,弄成了什么“高电压”“低电压”,在双绞线上传送了出去。晕~~出趟门就这么麻烦吗?
&&&&6.坐着双绞线旅游,爽!可当看到很多人坐着同轴电缆,还有坐光纤的时候,小德又感觉不是那么爽了。就在这时,来到了旅途的中转站------路由器。这地方可是高级场所,人家直接查看IP地址!剩下的一概不管,交给下面的人去做。够牛吧?路由器的内部也有一张表,叫做路由表,里面标识着哪一个网络的IP对应着路由器的哪一个端口。这个表也不是天生就有的,而是靠路由器之间互相“学习”之后生成的,当然也可以由管理员手工设定。这个“学习”的过程是依靠路由协议来完成的,比如RIP,EIGRP,OSPF等等。
&&&&7.当路由器查看了“小德”的IP地址以后,根据路由表知道了小德要去的网络,接着就把小德转到了相应的端口了。至此,路由器的主要工作完成,下面又是打包,封装成frame,转换成电压信号等一系列“折腾”的活,就由数据链路层和物理层的模块去干吧。
&&&&8.小德从路由器的出口出来,便来到了目的地----电脑B----所属的网络的默认网关。默认网关可以是路由器的一个端口,也可以是局域网里的各种服务器。不管怎样,下面的过程还是一样的:到交换机里的ARP表查询“小德”的IP地址,看看属于哪个局域网段或端口,然后就转发到B了。
&&&&9.进了B的网卡之后,还要层层“剥皮”,基本上和从A出来的程序是一样的------电脑B先校验一下CRC值,看看数据是否完整;然后检查一下frame的封装,看到是IP协议之后,就把“小德”交给IP“部门”了;IP协议一看目的地址,正确,再看看应用协议,是ICMP。于是知道了该怎么做了------产生一个回应数据包,(可以命名为“回应小德”),并准备以同样的顺序向远端的A发送。。至于刚刚收到的那个数据包就丢弃了。
&&&&10.“回应小德”这个数据包又开始了上述同样的循环,只不过这次发送者是B而接收者是A了。
&&&&以上是一个最简单的路由过程,任何复杂的网络都是在次基础之上实现的。
网络数据包大小&& &&&
& & 用UDP协议发送时,用sendto函数最大能发送数据的长度为:6=65507字节,其中20字节为IP包头长度,8字节为UDP包头长度。用sendto函数发送数据时,如果指的的数据长度大于该值,则函数会返回错误。
& & 用TCP协议发送时,由于TCP是数据流协议,因此不存在包大小的限制(暂不考虑缓冲区的大小),这是指在用send函数时,数据长度参数不受限制。而实际上,所指定的这段数据并不一定会一次性发送出去,如果这段数据比较长,可能会被分段发送,如果比较短,可能会等待和下一次数据一起发送。我在测试的时候,发现长度一般会被切成16384(16K)或49152(48K),不知道这两个值有什么意义。
二、网络中 IP数据报传输的过程伪代码【有助于理解】
IP数据报需从主机A上传送到主机B上,主机A首先查找路由表;
if(目的主机是与自己在同一个网段内)
& & 主机A查询自己的ARP表;
& & if(有该目的IP地址对应的MAC地址的记录)
将该MAC地址作为目的MAC地址,封装数据帧,传送给主机B;
& & & & & 发送一个ARP请求广播给网段内的所有主机,来查询该目的IP地址的MAC地址;
收到ARP请求报文的各个主机如果发现该IP地址是自己的IP地址,则返回一个ARP应答报文告诉主机A自己的MAC地址;
如果发现不是自己的IP地址,则丢弃该报文。
主机A收到这个应答报文后,就按照返回的MAC地址,将IP数据包封装成帧,然后发送到主机B上;
(补充:一般为了减少网络中的报文量,通信双方会维护一个各自的ARP表,把一次通信中获得IP MAC地址对保存在缓冲的ARP表中,但是ARP表有一个老化机制,删除一段时间内不用的IP
MAC地址对。)
else if(发现了能与目的网络号相匹配的表目)
则把报文发给改表目指定的下一站的路由器或直接连接的网络接口;
报文发送到下一站时,数据帧的目的MAC地址是下一个站路由器或者网络接口的MAC地址,而IP头部的目的IP地址是主机B的IP地址;
这里要指出的是:ARP请求报文以下一站路由器或网络接口的IP地址为目的IP地址,寻找真的目的MAC地址。换句话,ARP请求报文只负责IP数据报传输过程中每一跳中的目的MAC地址查询。
寻找标为“默认”的表目,把报文发送给该表目指定的下一站路由器;
报文发送到下一站时,数据帧的目的MAC地址是下一个站路由器的MAC地址,而IP头部的目的IP地址是主机B的IP地址。
数据帧在每两个网络设备间传递时,是转换成bit流在传输媒体上传输。链路层提供了如停止等待协议等机制,控制了bit流在传输媒体上的无措传输。
三、ARP协议详解
前言:ARP协议的作用:
1. 什么是ARP?   
ARP (Address Resolution Protocol) 是个地址解析协议。最直白的说法是:在IP以太网中,当一个上层协议要发包时,有了该节点的IP地址,ARP就能提供该节点的MAC地址。  
2为什么要有ARP?
OSI 模式把网络工作分为七层,彼此不直接打交道,只通过接口(layre interface). IP地址在第三层, MAC地址在第二层。
协议在发生数据包时,首先要封装第三层 (IP地址)和第二层 (MAC地址)的报头, 但协议只知道目的节点的IP地址,不知道其物理地址,又不能跨第二、三层,所以得用ARP的服务。
详细说明:
? 在网络通讯时,源主机的应用程序知道目的主机的IP地址和端口号,却不知道目的主机的硬件地址,而数据包首先是被网卡接收到再去处理上层协议的,如果接收到的数据包的硬件地址与本机不符,则直接丢弃。因此在通讯前必须获得目的主机的硬件地址。ARP协议就起到这个作用
? 当一台主机把以太网数据帧发送到位于同一局域网上的另一台主机时,是根据 48位的以太网地址来确定目的接口的,设备驱动程序从不检查 IP数据报中的目的IP地址。ARP(地址解析)模块的功能为这两种不同的地址形式提供映射:32位的 IP地址和 48位的以太网地址
(一)ARP报文各字段含义:
ARP报文字段总共有28个字节
1.硬件类型:占2个字节,表明ARP实现在何种类型的网络上。
? 值为1:表示以太网。
2.协议类型:占2个字节表示要映射的协议地址类型。
3.硬件地址长度:占1个字节,表示 MAC地址长度,其值为6个字节。
4.协议地址长度:占1个字节,表示IP地址长度,此处值4个字节
5.操作类型 :占2个字节,表示ARP数据包类型。
? 值为1表示ARP请求。
? 值2表示ARP应答。
6.源MAC地址:占6个字节,表示发送端MAC地址
7.源IP地址:占4个字节,表示发送端IP地址
8.目的以太网地址:占6个字节,表示目标设备的MAC物理地址
9.目的IP地址:占4个字节,表示目标设备的IP地址.
注意:在ARP操作中,有效数据的长度为28个字节,不足以太网的最小长度46字节长度,需要填充字节,填充字节最小长度为18个字节
(二)ARP请求分组或应答分组
以太网首部总共有14字节数据,arp请求报文总共有28字节。所以一个ARP请求分组或应答分组总共有46字节数据。
而以太网数据包的最小数据为60字节。所以,要对其进行填充。
这里有一些重复信息
1. 在以太网的数据帧报头中和ARP请求数据帧中都有发送端的MAC物理地址。
2. 在发送ARP请求时,以太网帧头中的目的MAC物理地址为FF-FF-FF-FF-FF-FF,而在ARP帧中的目的MAC处此时为空。
3. 对一个ARP请求来说,除ARP中目的端MAC硬件地址外的所有其他的字段都有填充值。当系统收到一份目的端为本地的ARP请求报文后,它就把硬件地址填进去,然后用两个目的端地址分别替换两个发送端地址,并把操作字段置为2,最后发送出去。
(三)ARP协议工作过程:
1. 原理:(ARP协议只使用于局域网中)
1& 在局域网中,网络中实际传输的是“帧”,帧里面是有目标主机的MAC地址的。
2& 在以太网中,一个主机要和另一个主机进行直接通信,必须要知道目标主机的MAC地址。但这个目标MAC地址是如何获得呢?它就是通过地址解析协议获得的。所谓“地址解析”就是主机在发送帧前将目标IP地址转换成目标MAC地址的过程。
3& ARP协议的基本功能就是通过目标设备的IP地址,查询目标设备的MAC地址,以保证通信的顺利进行。
4& 点对点的连接是不需要ARP协议的
2. 工作过程:
1& 当主机A向本局域网上的某个主机B发送IP数据报时,就先在自己的ARP缓冲表中查看有无主机B的IP地址。
2& 如果有,就可以查出其对应的硬件地址,再将此硬件地址写入MAC帧,然后通过以太网将数据包发送到目的主机中。
3& 如果查不到主机B的IP地址的表项。可能是主机B才入网,也可能是主机A刚刚加电。其高速缓冲表还是空的。在这中情况下,主机A就自动运行ARP。
(1)ARP进程在本局域网上广播一个ARP请求分组。ARP请求分组的主要内容是表明:我的IP地址是192.168.0.2,我的硬件地址是00-00-C0-15-AD-18.我想知道IP地址为192.168.0.4的主机的硬件地址。
(2)在本局域网上的所有主机上运行的ARP进行都收到此ARP请求分组。
(3)主机B在ARP请求分组中见到自己的IP地址,就向主机A发送ARP响应分组,并写入自己的硬件地址。其余的所有主机都不理睬这个ARP请求分组。ARP响应分组的主要内容是表明:“我的IP地址是192.168.0.4,我的硬件地址是08-00-2B-00-EE-AA”,请注意:虽然ARP请求分组是广播发送的,但ARP响应分组是普通的单播,即从一个源地址发送到一个目的地址。
(4)主机A收到主机B的ARP响应分组后,就在其ARP高速缓冲表中写入主机B的IP地址到硬件地址的映射。
3. 事例说明:用ping说明ARP工作的原理
假设我们的计算机IP地址是192.168.1.1,要执行这个命令:ping192.168.1.2。该命令会通过ICMP协议发送ICMP(以太网控制报文协议)数据包
该过程需要经过下面的步骤:  
1& 应用程序构造数据包,该示例是产生ICMP包,被提交给内核(网络驱动程序);   
2& 内核检查是否能够转化该IP地址为MAC地址,也就是在本地的ARP缓存中查看IP-MAC对应表;
3& 如果存在该IP-MAC对应关系,那么跳到步骤&7;
如果不存在该IP-MAC对应关系,那么接续下面的步骤;
4& 内核进行ARP广播,目的MAC地址是FF-FF-FF-FF-FF-FF,ARP命令类型为REQUEST(1),其中包含有自己的MAC地址;   
5& 当192.168.1.2主机接收到该ARP请求后,就发送一个ARP的REPLY(2)命令,其中包含自己的MAC地址;   
6& 本地获得192.168.1.2主机的IP-MAC地址对应关系,并保存到ARP缓存中;   
7& 内核将把IP转化为MAC地址,然后封装在以太网头结构中,再把数据发送出去;  
4. 特殊情况:
ARP是解决同一个局域网上的主机或路由器的IP地址和硬件地址的映射问题。如果所要找的目标设备和源主机不在同一个局域网上。
1&此时主机A就无法解析出主机B的硬件地址(实际上主机A也不需要知道远程主机B的硬件地址);
2&此时主机A需要的是将路由器R1的IP地址解析出来,然后将该IP数据报发送给路由器R1.
3&R1从路由表中找出下一跳路由器R2,同时使用ARP解析出R2的硬件地址。于是IP数据报按照路由器R2的硬件地址转发到路由器R2。
4&路由器R2在转发这个IP数据报时用类似方法解析出目的主机B的硬件地址,使IP数据报最终交付给主机B.
? 如果你的数据包是发送到不同网段的目的地,那么就一定存在一条网关的IP-MAC地址对应的记录。   
? 知道了ARP协议的作用,就能够很清楚地知道,数据包的向外传输很依靠ARP协议,当然,也就是依赖ARP缓存。要知道,ARP协议的所有操作都是内核自动完成的,同其他的应用程序没有任何关系。同时需要注意的是,ARP协议只使用于本网络。
(四)ARP缓冲表和TTL
1. ARP缓冲表
1& ARP协议的本质是完成网络地址到物理地址的映射。从概念上将就是找到一个映射方法f,使得“物理地址 = f(网络地址)“。物理地址有两种基本类型:以太网类型和令牌环网类型。网络地址特指IP地址,对映射方法的要求就是高效。具体到以太网,它使用的是动态绑定转换的方法。一般是设置ARP高速缓存,通过学习,老化,更新,溢出算法处理ARP映射表来解决这些问题。
? 学习指ARP收到任何指向本结点IP地址的ARP/IP包,从中提取出地址对,当ARP缓冲表中无对应项时,由ARP接收部分添加;
? 老化指为每项设置寿命域,以便代谢掉陈旧的地址映射项;
? 更新指ARP提取到新的地址对时,用其更新缓存里已有的对应项;
? 溢出算法指当缓存慢时,采取何种方法替代旧有的地址对。
2& ARP缓存表由状态,寿命,IP地址,MAC地址4个字段组成。状态字段指示地址对是否有效;寿命字段用于老化操作,初始存入最大值,以后由OS时间函数调用,每秒减1,直至为0清除;IP地址和MAC地址字段保存网络地址和物理地址的映射。围绕ARP缓存表,完成了4种操作:学习,老化,更新,表满处理。
3& 当ARP被询问一个已只IP地址节点的MAC地址时,先在ARPcache 查看
l 若存在,就直接返回MAC地址,
l 若不存在,才发送ARP request向局域网查询。
4& 当主机A向B发送数据报时,很可能以后不久主机B还要向A发送数据报,因而主机B可能要向A发送ARP请求分组。
所以,为了减少网络上的通信量,主机A在发送其ARP请求分组时,就将自己的IP地址到硬件地址的写入主机B自己的ARP高速缓冲表中。这对主机B以后向A发送数据报时就更方便了。
Tiger 说明:
任何事物都有两面性,如果掌握的好它就是天使,如果掌握的不好它就是Satan,ARP中的缓冲表为计算机之间的通信效率和减少网络通信量之间作出了巨大的贡献,但是它同时为我们上网时留下了安全隐患;例如交换机嗅探(在下面会有介绍)
2. ARP中的TTL(即上面所说的寿命域)
ARP将保存在高速缓冲表中的每一个映射地址表项都设置了TTL(生存时间),只要TTL小于0的项目就从高速缓冲表中删除掉。
(ARP的超时值一般为20分钟,对不完整的表项设置为20分钟,而对不完整的表项设置为2分钟《不完整的表项:即在以太网上对一个不存在的主机发出ARP请求》,当这些表项再次使用时,这些实现一般都把超时值重新设为20分钟。)
好处:主机A和B通信。A的ARP高速缓冲表里保存有B的物理地址。但B的网卡突然坏了,B立即就更换了一块,因此B的硬件地址就改变了。A还要和B继续通信。A在其ARP缓冲表中查找到B原先的硬件地址,并使用该硬件地址向B发送数据帧。但B原先的硬件地址已经失效了。因此A无法找到主机B。但是过了一段时间,A的ARP高速缓冲表中已经删除了B原先的硬件地址(因为它的生存时间到了),于是A重新光播发送ARP请求分组,又找到了B。
(五)ARP命令:
1. 使用arp-a命令就可以查看本地的ARP缓存内容,所以,执行一个本地的PING命令后,ARP缓存就会存在一个目的IP的记录了。
2. 使用arp –d来删除ARP高速缓存中的某一项内容
3. 使用arp –s来增加高速缓冲表中的内容,这个命令需要主机名和以太网地址。新增加的内容是永久性的,除非在命令行的末尾加上关键字temp。
arp –s 157.55.85.212 00-aa-aa-562-c6-09
增加一个静态的ARP表项。
4. arppub –s:使系统起着主机ARP代理功能。系统将回答与主机名对应的IP地址的ARP请求。
(六)ARP其他方面
1.交换网络的嗅探
1&1.ARP协议并不只在发送了ARP请求才接收ARP应答
当计算机接收到ARP应答数据包的时候,就会对本地的ARP缓存进行更新,将应答中的IP和MAC地址存储在ARP缓存中。
因此,在上面的假设网络中,B向A发送一个自己伪造的ARP应答,而这个应答中的数据为发送方IP地址是192.168.10.3(C的IP地址),MAC地址是DD-DD-DD-DD-DD-DD(C的MAC地址本来应该是CC-CC-CC-CC-CC-CC,这里被伪造了)。当A接收到B伪造的ARP应答,就会更新本地的ARP缓存,将本地的IP-MAC对应表更换为接收到的数据格式,由于这一切都是A的系统内核自动完成的,A可不知道被伪造了。ARP欺骗的主要用途就是进行在交换网络中的嗅探。
2.IP地址冲突
1&如果网络中存在相同IP地址的主机时候,就会报告出IP地址冲突的警告。
2&如何产生?
? 比如某主机B规定IP地址为192.168.0.1,如果它处于开机状态,那么其他机器A更该IP地址为192.168.0.1就会造成IP地址冲突。
? 其原理是:主机A在连接网路(或更改IP地址)的时候就会向网络发送ARP包广播自己的IP地址,也就是free arp(免费ARP).如果网络中存在相同IP地址的主机B,那么B就会通过ARP来reply该地址,当A接收到这个reply后,A就会跳出IP地址冲突的警告,当然B也会有警告。因此用ARP欺骗可以来伪造这个ARPreply,从而使目标一直遭受IP地址冲突警告的困扰。
3.阻止目标的数据包通过网关
1&比如在一个局域网内通过网管上网,那么连接外部的计算机上的ARP缓存中就存在网管IP-MAC对应记录
2&如果,该记录被更改,那么该计算机向外发送的数据包总是发送到了错误的网关硬件地址上,这样,该计算机就不能上网了。
3&这里也主要是通过ARP欺骗进行的。有两种方法达到这样的目的:
? 向目标发送伪造的ARP应答数据包,其中发送方的IP地址为网管的地址,而MAC地址则为一个伪造的地址。当目标接收到ARP包,那么就更新自身的ARP缓存。如果该欺骗一直持续下去,那么目标的网管缓存一直是一个被伪造的错误记录。不过,如果使用arp –a,就知道问题所在了。
? 第二种方法是欺骗网管。向网管发送伪造的ARP应答数据包,其中发送方的IP地址为目标的IP地址,而MAC地址则为一个伪造的地址。这样,网管上的目标ARP记录就是一个错误的,网管发送给目标的数据报都是使用了错误的MAC地址。这种情况下,目标能够发送数据到网管,却不能接收到网管的任何数据。同时,目标自己查看arp –a却看不出任何问题来。
4.通过检测混杂模式节点
1&在混杂模式中,网卡进行包过滤不同于普通模式。本来在普通模式下,只有本地地址的数据包或者广播(多播等)才会被网卡提交给系统核心,否则的话,这些数据包就直接被网卡抛弃。现在,混合模式让所有经过的数据包都传递给系统核心,然后被sniffer等程序利用。   
2&通过特殊设计的ARP请求可以用来在一定程度上检测处于混杂模式的节点,比如对网络中的每个节点都发送MAC地址为FF-FF-FF-FF-FF-FE的ARP请求。对于网卡来说这不是一个广播地址(FF-FF-FF-FF-FF-FF),所以处于普通模式的节点就会直接抛弃该数据包,但是多数操作系统核心都认为这是一个广播地址,如果有一般的sniffer程序存在,并设置网卡为混杂模式,那么系统核心就会作出应答,这样就可以判断这些节点是否存在嗅探器了。
3&可以查看,很多基于ARP的攻击都是通过ARP欺骗实现的。至于ARP欺骗的防范,还是尽可能使用静态的ARP。对于WIN,使用arp-s来进行静态ARP的设置。
当然,如果能够完全使用静态的IP+MAC对应,就更好了,因为静态的ARP缓存只是相对的。当然,可以有一些方法来实现ARP欺骗的检测。设置一个ARP的嗅探器,其中维护着一个本地网络的IP-MAC地址的静态对应表,查看所有经过的ARP数据,并检查其中的IP-MAC对应关系,如果捕获的IP-MAC对应关系和维护的静态对应关系对应不上,那么就表明是一个欺骗的ARP数据包了。
四、电脑本机的子网掩码工作过程(我猜测)
网卡收到第三层数据包(仅含有IP地址)后,要对其进行帧封装,以便通过第二层链路层发送出去,此时需要填充目的地址的mac地址。
& & 首先判断目的IP地址是否在本子网内(通过子网掩码判断),如果是,则在arp缓存中查找(或查找不到时启动arp协议询问),如果找到则填充目的mac地址,并通过网卡发到直连的交换机上(或集线器或路由器一端),以后数据包就由交换机或路由器负责传输下去了,如果找不到,说明本子网内根本不存在此目的ip地址,即要发往的地址不存在,则返回超时错误。
& & 然后判断出IP地址不在本子网内,则找到本机的默认网关的IP地址,表明应该先把该数据包发往默认网关机器上,此时利用arp协议查找默认网关IP地址对应的默认网关机器的mac地址,然后把数据包填充上默认网关机器的mac地址,然后发网路由器,因为此时的数据帧的目的mac地址写的是默认网关的mac地址,交换机(或路由器)接收的数据包后,会发往默认网关机器。以后数据包就由默认网关继续往下传输了。
本文已收录于以下专栏:
相关文章推荐
ping指定数据包大小linux下ping包的默认大小为64Byte,次数不限。但有时我们需要尝试ping大数据包,来测试网络的状况,这时,就要指定ping包的大小了。Linux下ping大数据包的格...
TCP通讯是流协议,它不像UDP那样基于包为边界的通讯方式,
TCP流式协议,举个简单例子,一端用send 分别发送 100,123,120字节的数据,
另一端用recv可以一下子接收到 100+12...
程序人生 | 4个方法快速打造你的阅读清单作者:foruok
下面提供四种方法,无论你是否经常读书,都可以使用它们快速构建起你的阅读清单:
从问题到图书
一看就会的4种找书方法,从此告别“该读什么”的苦恼
PC1、R1、R2、WebServer
PC1 为网络A中的一台主机,WebServer为网络B中的Web服务器,路由器R1、R2分别为网络A、B的网关,且路由器R1、R2的WAN口相连。
hosts文件位置、hosts文件是什么?hosts文件修复方法的详细介绍
详细出处参考:http://www.jb51.net/os/windows/36843.html
昨天把项目发布到测试服务器上面去,可报表老是出不来,报错也很奇怪:java.lang.reflect.InvocationTargetExceptionat sun.reflect.NativeMet...
转自:http://blog.csdn.net/bad_sheep/article/details/6158676
以下部分内容是自己的理解,可能会有差错,如有发现,欢迎指正。
首先要看TCP/IP协议,涉及到四层:链路层,网络层,传输层,应用层。   
其中以太网(Ethernet)的数据帧在链路层   
IP包在网络层   
TCP或UDP包在传输层   
路由选择是发生在互联网络(如通过路由器连接的独立网络)上的数据分组转发过程,如下图所示。当主机发送数据分组时,它或者是对于同一网络上的本地主机或者是对于远程网络上的主机。如果数据分组没有本地IP网络地...
他的最新文章
讲师:宋宝华
讲师:何宇健
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 stm32 i2c通信协议 的文章

 

随机推荐