• uip UDP server广播模式(client能够随意port,而且主动向client发送数据)


    眼下移植uip,发现UDP server模式下,必须指定本地port以及clientport,否则仅仅能讲clientport设置为0,才干接收随意port的数据,可是无法发送数据,由于此时clientport设置为0了,我通过将原始数据包中的clientport保存下来,而且在发送的时候将clientport替换为指定的port,发送完毕之后又设置为0,这样就实现了向随意clientport发送数据.


    uip.c

        if(uip_udp_conn->lport != 0 &&
           UDPBUF->destport == uip_udp_conn->lport &&
           (uip_udp_conn->rport == 0 ||
            UDPBUF->srcport == uip_udp_conn->rport) &&
           (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) ||
    	uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) ||
    	uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) {

     (uip_udp_conn->rport == 0 ||
            UDPBUF->srcport == uip_udp_conn->rport) &&
    这句就限制了client端口为0或者指定端口


    //udp_server.c

    /*************************************************************************************************************
     * 文件名称:			udp_server.h
     * 功能:			uIP UDP服务器相关函数
     * 作者:			cp1300@139.com
     * 创建时间:		2014-06-04
     * 最后改动时间:	2014-06-04
     * 具体:			UDP服务器相关函数
    *************************************************************************************************************/	
    #include "SYSTEM.h"
    #include "tapdev.h"
    #include "uip.h"
    #include <string.h>
    #include <stdio.h>	
    #include "uIP_user.h"
    #include "udp_server.h"
    #include "appconfig.h"
    
    u16 UDP_ServerPort = UDP_SERVER_PORT;			//UDP服务器本地port,用于新数据port识别
    UIP_USER udp_server;							//UDP 服务器数据结构
    static bool isAnyPort = FALSE;					//client随意port标志
    
    
    
    /*************************************************************************************************************************
    * 函数			:	void udp_server_connected(u16 ServerPort,u16 ClientPort)
    * 功能			:	建立一个UDP服务器(广播方式)
    * 參数			:	ServerPort:服务器本地port,ClientPort:clientport,0:随意port;非0:指定port
    * 返回			:	无
    * 依赖			:	uip
    * 作者			:	cp1300@139.com
    * 时间			:	2014-06-04
    * 最后改动时间	: 	2014-06-05
    * 说明			: 	必须放在UDPclient初始化之前
    *************************************************************************************************************************/
    void udp_server_connected(u16 ServerPort,u16 ClientPort)
    {
    	UDP_ServerPort = ServerPort;							//本地port
    	uip_listen(HTONS(ServerPort));
    	uip_udp_bind(&uip_udp_conns[0], htons(ServerPort));		//绑定本地port
    	udp_server.RxLen = 0;
    	udp_server.TxLen = 0;
    	udp_server.ServerPort = ServerPort;						//服务器port
    	if(ClientPort != 0)										//指定port
    	{
    		uip_udp_conns[0].rport = HTONS(ClientPort);
    		udp_server.ClientPort = ClientPort;
    		isAnyPort = FALSE;									//client指定port
    	}
    	else
    	{
    		uip_udp_conns[0].rport = 0;
    		isAnyPort = TRUE;									//client随意port
    	}
    }
    
    
    
    
    /*************************************************************************************************************************
    * 函数			:	void udp_server_appcall(void)
    * 功能			:	服务器回调函数,用于uip处理数据
    * 參数			:	无
    * 返回			:	无
    * 依赖			:	uip
    * 作者			:	cp1300@139.com
    * 时间			:	2014-06-04
    * 最后改动时间	: 	2014-06-05
    * 说明			: 	无
    *************************************************************************************************************************/
    void udp_server_appcall(void)
    {
    	
    	if (uip_newdata())
        {
    		if(uip_datalen() > UIP_RX_BUFF_ZISE) uip_len = UIP_RX_BUFF_ZISE;	//大小限制
    		memcpy(udp_server.RxBuff, uip_appdata, uip_len);					//复制接收的数据到接收缓冲区
    		udp_server.RxLen = uip_len;											//存储接收数据长度
    		udp_server.ClientPort = (u16)(uip_buf[34]<<8) | uip_buf[35];		//强制获取clientport地址
    		//uart_printf("%s
    ",(char*)uip_appdata);
        }
    	//新数据到达,轮询,发送数据 
    	if(uip_newdata() || uip_poll())
    	{
    		if(udp_server.TxLen) 
    		{
    			uip_send(udp_server.TxBuff, udp_server.TxLen);	//发送UDP数据包
    			udp_server.TxLen = 0;
    		}
    	}
    }	
    
    
    /*************************************************************************************************************************
    * 函数			:	void udp_ServerSendDataPackage(u8 *pBuff, u16 len,u16 ClientPort)
    * 功能			:	UDP 服务器发送数据
    * 參数			:	pBuff:发送数据缓冲区,len:发送数据长度,ClientPort:clientport
    * 返回			:	无
    * 依赖			:	uip
    * 作者			:	cp1300@139.com
    * 时间			:	2014-06-04
    * 最后改动时间	: 	2014-06-05
    * 说明			: 	无
    *************************************************************************************************************************/
    void udp_ServerSendDataPackage(u8 *pBuff, u16 len,u16 ClientPort)
    {
    	if(len > UIP_TX_BUFF_ZISE) len = UIP_TX_BUFF_ZISE;
    	memcpy(udp_server.TxBuff, pBuff, len);
    	udp_server.TxLen = len;
    	uip_udp_conns[0].rport = HTONS(ClientPort);			//临时将clientport设置为上一次发送数据的clientport
    }
    
    
    
    
    /*************************************************************************************************************************
    * 函数			:	void udp_ServerSendEndCallBack(u16 conn)
    * 功能			:	UDP发送数据完毕回调函数,眼下仅仅支持一个服务器port
    * 參数			:	pBuff:发送数据缓冲区,len:发送数据长度,ClientPort:clientport
    * 返回			:	无
    * 依赖			:	uip
    * 作者			:	cp1300@139.com
    * 时间			:	2014-06-04
    * 最后改动时间	: 	2014-06-05
    * 说明			: 	因为UDP服务器的clientIP设置为0后能够接收随意port发来的数据,可是却无法发送数据
    					到0port,因此在发送前将clientport设置为实际port,发送完毕后改动为0
    *************************************************************************************************************************/
    void udp_ServerSendEndCallBack(u16 conn)
    {
    	if((conn == 0) && (isAnyPort == TRUE))
    	{
    		uip_udp_conns[conn].rport = 0;		//将port设置为0
    	}
    }
    


    //udp_server.h

    /*************************************************************************************************************
     * 文件名称:			udp_server.h
     * 功能:			uIP UDPserver相关函数
     * 作者:			cp1300@139.com
     * 创建时间:		2014-06-04
     * 最后改动时间:	2014-06-04
     * 具体:			UDPserver相关函数
    *************************************************************************************************************/	
    #ifndef _UDP_SERVER_H_
    #define _UDP_SERVER_H_
    #include "tcp.h"
    #include "uip.h"
    #include "system.h"
    #include "uIP_user.h"
    
    extern UIP_USER udp_server;	//UDP server数据结构
    extern u16 UDP_ServerPort;	//UDPserver本地port
    
    
    void udp_server_connected(u16 ServerPort,u16 ClientPort);				//建立一个UDPserver(广播方式)
    void udp_server_appcall(void);											//server回调函数,用于uip处理数据
    void udp_ServerSendDataPackage(u8 *pBuff, u16 len,u16 ClientPort);		//UDP server发送数据
    void udp_ServerSendEndCallBack(u16 conn);								//UDP发送数据完毕回调函数
    
    
    
    
    #endif //_UDP_SERVER_H_
    


    //结构体定义

    //用户连接数据结构
    #define UIP_RX_BUFF_ZISE	512		//接收数据缓冲区大小
    #define UIP_TX_BUFF_ZISE	512		//发送数据缓冲区大小
    typedef struct
    {
    	u16 RxLen;		//接收数据长度
    	u16	TxLen;		//发送数据长度
    	u16 ClientPort;	//clientport
    	u16	ServerPort;	//serverport
    	u8	RxBuff[UIP_RX_BUFF_ZISE];	//接收缓冲区
    	u8	TxBuff[UIP_TX_BUFF_ZISE];	//接收缓冲区
    }UIP_USER;

    //配置定义

    #define DHCP_TIME_OUT				60					//DHCP获取超时时间,单位S
    #define TCP_LINK_SERVER_TIME_OUT	10					//连接server超时时间,单位S
    #define TCP_LINK_SERVER_CNT			5					//连接server重试次数
    #define TCP_CLIENT_PORT_AUTO		1					//clientport随机分配
    #define TCP_CLIENT_DEFAULT_PORT		2400				//client默认port
    #define TCP_SERVER_DEFAULT_IP		192,168,16,104		//server默认IP地址
    #define TCP_SERVER_DEFAULT_PORT		8888				//server默认port
    #define TCP_SEND_TIME_OUT			5					//数据发送超时时间,单位S
    
    #define UDP_LOCAL_PORT				8000				//UDP连接本地port
    #define UDP_REMOTE_PORT				8899				//UDP连接远程port
    #define UDP_SERVER_PORT				8100				//UDPserver本地port

    //数据port调度

    //UDP应用接口函数(UIP_UDP_APPCALL)
    void udp_appcall(void)
    {	
    
    	switch(uip_udp_conn->lport)//本地监听端口
    	{
    		//用于DHCP
    		case HTONS(67):	dhcpc_appcall();break;
    		case HTONS(68):	 dhcpc_appcall();break;
    		default: 
    		{
    			if(uip_udp_conn->lport == HTONS(UDP_ClinetPort))		//UDP客户端
    			{
    				udp_client_appcall();
    			}
    			else if(uip_udp_conn->lport == HTONS(UDP_ServerPort))	//UDP服务器
    			{
    				udp_server_appcall();
    			}
    		}break;
    	}		      
    }
    

    //UDP调度处理,必须在数据发送完毕后调用自己定义的回调函数

    			for(i = 0; i < UIP_UDP_CONNS; i++)
    			{
    				//仅仅处理发送事件
    				uip_udp_periodic(i);	//处理UDP通信事件
    				//当上面的函数运行后。假设须要发送数据,则全局变量uip_len>0
    				//须要发送的数据在uip_buf, 长度是uip_len (这是2个全局变量)
    				if(uip_len > 0)
    				{
    					LED2 = ~ LED2;
    					uip_arp_out();//加以太网头结构,在主动连接时可能要构造ARP请求
    					tapdev_send();//发送数据到以太网
    					udp_ServerSendEndCallBack(i);	//数据发送完毕后一定要调用回调函数
    					break;
    				}
    			}
    调用这个实现将clientport设置为0,这样就能够接受来自随意port的数据
    udp_ServerSendEndCallBack(i);	//数据发送完毕后一定要调用回调函数




    //初始化并处理UDPserver数据

    //实现收到后马上返回数据

    udp_server_connected(UDP_SERVER_PORT, 0);	//新建UDP服务器,client随意port

    //UDP服务器数据处理
    		if(udp_server.RxLen > 0)
    		{
    			
    			uart_printf("服务器port:%d
    ",udp_server.ServerPort);
    			uart_printf("clientport:%d
    ",udp_server.ClientPort);
    			uart_printf("UDP Server Rx(%dB):%s
    ",udp_server.RxLen,(char*)udp_server.RxBuff);
    			udp_ServerSendDataPackage(udp_server.RxBuff, udp_server.RxLen, udp_server.ClientPort);
    			udp_server.RxLen = 0;
    		}


    //仿真结果




  • 相关阅读:
    虚基类、虚函数与纯虚函数
    从尾到头打印链表
    Login
    (转)学习技术的三部曲:WHAT、HOW、WHY
    win7mstsc连接电脑
    C#面试题
    ASP.net C#笔记 (一)新建三层项目
    asp.net (一) 语法
    云服务器寻找
    VB.net笔记 (二)内置对象
  • 原文地址:https://www.cnblogs.com/yfceshi/p/6978255.html
Copyright © 2020-2023  润新知