这里对的文章的篇幅限制了大小,在一个上面实在写不下了就另起了一篇。哎
我们继续讲一下如何接收一个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代码。遇到问题可以与我沟通,我的邮箱,但是请不要向我要源代码,不是我吝啬这么几行代码,实际代码中包含的内容比较复杂,而写在上面的代码是原理性的,已经足够实际应用的了。
限于水平,本文难免有不妥或错误,恳请大家及时向我反馈。发现错误我会及时更新。
【全文完】