⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udp_api.c

📁 基于STM32F107的UDP服务器程序
💻 C
字号:
#include "stm32_eth.h"
#include "netconf.h"
#include "lwip/ip_addr.h"
#include "lwip/mem.h"
#include "lwip/udp.h"
#include "Udp_Api.h"
#include "GData.h"

#include <usart.h>
#include <stdio.h>
/***************************************************/
#define  server_port 99
extern u8 SizeOfInfor;
extern u8 Rx_infor[1500];
extern u16 NumInfor;
u8 SnPbufTimes=2;
extern void Delay_ARMJISHU(__IO uint32_t nCount);
/****************************************************
*函数功能:初始化udp,选定通信端口,建立连接机制
****************************************************/
void Udp_Api_init(void)
{
  err_t err;
  struct udp_pcb *UDPpcb;

  /* create a new UDP PCB structure  */
  UDPpcb = udp_new();
  if (!UDPpcb)
  {  /* Error creating PCB. Out of Memory  */
    return;
  }

  /* Bind this PCB to port 99  */
  err = udp_bind(UDPpcb, IP_ADDR_ANY, server_port);
  if (err != ERR_OK)
  {    /* Unable to bind to port  */
    return;
  }

  //通知协议栈当99端口有连接请求时调用recv_callback_udp
  udp_recv(UDPpcb, recv_callback_udp, NULL); 
}
/****************************************************
*函数功能:	 对接收数据的处理函数(数据接受在以太网中断中完成)
****************************************************/
 void recv_callback_udp(void *arg,struct udp_pcb *upcb, struct pbuf *pkt_buf,
                        struct ip_addr *addr,u16_t port)
{
		struct ip_addr dAddr = *addr; //结构体赋值
		u8 *pValiData;
		u16 i,j;

		struct pbuf *p[10] ; //内存池中只有10个pbuf结构
		struct ip_addr ipaddr;
		struct udp_pcb *UDPpcb1;
		u32_t IPaddress;

		pValiData=(u8*)pkt_buf->payload;    //u8* 对void指针进行强制转换		 	    
		printf("%接收到数据:%d\n\r",*pValiData);
		IPaddress = addr->addr;	  //远端IP地址
            
		if( pkt_buf != NULL )
        {
          switch (*pValiData)
		  {		  
		  case 0x05:  		          				  
				  udp_sendto( upcb , pkt_buf , &dAddr , port ) ;	 //返回原来的pkt_buf
				  break;
		  case 0x0A:		  			     
				  p[0] = pbuf_alloc(PBUF_TRANSPORT,SizeOfInfor*NumInfor,PBUF_RAM); //根据data大小开辟内存,在RAM中
				  for(i=0;i<SizeOfInfor*NumInfor;i++)							   //将数据复制到开辟pbuf的内存中
					 *((u8*)p[0]->payload + i)=Rx_infor[i];
				  for(j=1;j<SnPbufTimes;j++)
				  {
				      p[j]=pbuf_alloc(PBUF_RAW,SizeOfInfor*NumInfor,PBUF_RAM);
					  for(i=0;i<SizeOfInfor*NumInfor;i++)
				         *((u8*)p[j]->payload + i)=Rx_infor[i];
					  p[j-1]->next = p[j]; //创建链表
					  //p[j]->ref +=1; //被引用次数加1 ,pbuf->ref=1时才能删除pbuf
				  }				  
				  for(j=SnPbufTimes-1;j>0;j--)	//计算tot_len
					  p[j-1]->tot_len = p[j-1]->len + p[j]->tot_len;
//                  p->payload = (u8 *)Rx_infor;
   				  
                  IP4_ADDR(&ipaddr,(u8_t)(IPaddress),		  //192
				                   (u8_t)(IPaddress >> 8),	  //168
								   (u8_t)(IPaddress >> 16),	  //1
								   (u8_t)(IPaddress >> 24) ); //2						   
                  UDPpcb1 = udp_new();  
                  udp_bind(UDPpcb1,IP_ADDR_ANY,server_port);  //绑定本地IP 地址      
                  udp_connect(UDPpcb1,&ipaddr,port);  //连接远端IP

				  udp_send(UDPpcb1,p[0]);
				  printf(" %d ",0);
				  Delay_ARMJISHU(0xFFFF);
//				  for(i=1;i<SnPbufTimes;i++)
//				  {
//                       udp_bind(UDPpcb1,IP_ADDR_ANY,server_port);  //绑定本地IP 地址
//					   udp_connect(UDPpcb1,&ipaddr,port);  //连接远端IP
//					   udp_send(UDPpcb1,p[i]);		
//					   p[i]->ref -=1;
//					   printf(" %d ",i);
//					   Delay_ARMJISHU(0xFFFF);		               
//				  }			   
				  
				  pbuf_free(p[0]); //将链表中从前往后ref=1的pbuf连续删去 				  
				  udp_remove(UDPpcb1); //在不需要改pcb通信连接时可以删去,	 
				  break;
			     //udp_sendto( upcb , pkt_buf , &dAddr , port ) ;
		  default:
		          printf("%客户端UDP端口:%d\n\r",port);
		          break;
  		  }
        }
        pbuf_free(pkt_buf);
}
/**************************************************************
*
**************************************************************/
void process_udp_request(struct pbuf *pkt_buf, struct ip_addr *addr, u16_t port)
{
//  u32_t IPaddress = addr->addr;
//  struct ip_addr ipaddr=*addr;
//  struct pbuf *p;
//  struct udp_pcb *UDPpcb1;
//  u8 *pValiData= pkt_buf->payload; 	 //此处要指定接收到的数据类型u8
//  if( pkt_buf != NULL)
//  {
//	  switch (*pValiData)
//	  {
//	       case 0x05: //读开门记录
//		          *pValiData +=5;
//		          udp_sendto( upcb , pkt_buf , &ipaddr , port ) ;
//				  break;
//		   case 0x0A:
//		          *pValiData +=5;
//		          udp_sendto( upcb , pkt_buf , &ipaddr , port ) ;
//		           break;
//			default:  break;
//	  }
//  }
}
/*
p = pbuf_alloc(PBUF_RAW,sizeof(UDPData),PBUF_RAM); 
                  p->payload=(void *)UDPData; 
   
                  IP4_ADDR(&ipaddr,(u8_t)(IPaddress),		  //192
				                   (u8_t)(IPaddress >> 8),	  //168
								   (u8_t)(IPaddress >> 16),	  //1
								   (u8_t)(IPaddress >> 24));  //2
                  UDPpcb1 = udp_new(); 
 
                  udp_bind(UDPpcb1,IP_ADDR_ANY,service_port);  //绑定本地IP 地址      
                  udp_connect(UDPpcb1,&ipaddr,1000);  
                  udp_send(UDPpcb1,p);
		          //udp_remove(upcb);
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -