Chinaunix首页 | 论坛 | 博客
  • 博客访问: 393639
  • 博文数量: 69
  • 博客积分: 1992
  • 博客等级: 上尉
  • 技术积分: 1162
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-03 19:50
文章分类
文章存档

2015年(1)

2011年(55)

2010年(13)

分类: LINUX

2011-04-23 10:26:36


可运行在单片机上的UDP通讯协议的实现【下】
2010年05月10日 星期一 20:22

    这里对的文章的篇幅限制了大小,在一个上面实在写不下了就另起了一篇。哎

    我们继续讲一下如何接收一个udp包。但从上面所讲的内容来看,我们队端口并不关心,如果也不验证检验和的话,对udp包并不需要特别处理。所以这里我就不写udp包的处理函数,而直取出数据。下面,修改一下刚写好的main函数如下:

#define DATA_REBUF (unsigned char *)&transmit_buffer[28]

void main(void)
{
unsigned long a;//定义几个临时变量

/***********
一些初始化等操作在此处进行,这里省略
************/

for(a = 10000000; a > 0; a--);//延时
printf("\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nSend ARP request ... ");
//用串口打印一串字符,这是根据自己的处理器自行添加的函数,用于查看调试信息

//首先通过arp协议寻找上位机
while(1)
{
arp_request();//发出arp请求
while(/*等待中断标志或某种标识来判断是否有数据包被接收到,没有数据包时为真,有数据包收到时为假*/);
//上面的语句会根据不同的网卡芯片和不同的处理器,判断方式会有所不同。
tem = receivepacket();
if(tem == 0x0806)//判断是否是arp协议
{
    if(ARP_SAVETHEREPLY == arp_process(receive_packet_length))break;
    //判断是否是arp应答,如果是则存储上位机mac地址后退出循环
}
for(a = 5000000; a > 0; a--);//适当的延时1秒左右
}

printf("Received ARP replay\r\n----------------------------\r\n\r\n");
//打印ARP通讯完成信息。以上是ARP通讯,与之前的一样,下面开始接收udp包

while(1)
{
   printf("Waiting for a new packet : \r\n\t");//打印正在等待接收数据包
   while(/*等待中断标志或某种标识来判断是否有数据包被接收到,没有数据包时为真,有数据包收到时为假*/);
   a = receivepacket(re_data);//读取数据包信息,返回协议类型(ip协议或arp协议)
   if(a == ETHTYPE_IP) //判断是否是ip协议包
   {
    a = ip_process(); //处理ip协议,返回ip协议中承载的协议类型
    if(a == IP_UDP) //判断是否是udp协议包
    {
      printf("Received a udp packet ( %d ) bytes )", receive_packet_length - 8);
     //打印udp包数据,数据长度需减去8个字节的udp首部
      for(a = 0; a < (receive_packet_length - 8); a++)
      {
       printf("%d ",DATA_REBUF[a]);//从接收数据缓存中读取数据并打印
      }
      printf("\r\n\r\n\r\n\r\n"); 
      break;//成功接收到一个udp包后便跳出循环停止程序
    }
    else if(a == IP_NOTMYIP)printf("Received but not my IP Packet\r\n");
    else if(a == IP_BED_PACKET)printf("Received my IP Packet but not valid yet\r\n");
    else printf("Error!\r\n");//非正常ip协议包的其它情况打印输出
   }
   else
   {
    printf("Received but not a IP Packet!\r\n");//非ip协议包情况打印输出
    continue;
   }
}

while(1);//程序停止,查看结果
}

注:以上所有的“printf()”函数均为通过串口输出的调试信息,并且仅为表意而非可执行代码,也就是需要用自己的串口代码根据注释内容代替的。

    调试结果,直接上图:


    代码中arp通讯一般比较容易实现,也可能需要几秒钟时间等待。在基板与上位机直连的情况下,上位机会经常发一些寻址包(包括arp包或类似arp协议的ip包),图中接收到6个。我将前面发送的udp数据包经过简单修改直接发回,数据内容没变,在udp校验和关闭的情况下,基板可以成功接收到一个udp数据包,如图中最后一个包所示。从这个main函数中我们可以分析出来,解析接收数据包的过程可以逐层进行。首先,从最原始的数据包中得到最底层协议类型(arp协议或ip协议)和整个数据包的长度;然后,根据得到的协议类型调用响应的函数来处理,arp协议的处理可以直接通过处理函数完成,而ip协议的处理会返回一个上层协议类型(这里我们只接收udp协议);最后,在根据ip协议的返回结果调用函数或直接处理结果。

    至此,如何发送和接收一个udp数据包通过以上介绍便可以实现起来。本人不大善于文笔,很多地方写的不够简练,还有很多重复。其实调试这样一个程序要比写这样一个东西容易很多。时间关系,本文没能够一次完成,所以前后的代码可能不够连贯,也难免会出错。也请大家根据文字解释来理解而不是简单的copy代码。遇到问题可以与我沟通,我的邮箱,但是请不要向我要源代码,不是我吝啬这么几行代码,实际代码中包含的内容比较复杂,而写在上面的代码是原理性的,已经足够实际应用的了。

    限于水平,本文难免有不妥或错误,恳请大家及时向我反馈。发现错误我会及时更新。

【全文完】

阅读(2872) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~