目前移植了UDP客户端模式,测试使用广播地址.
//udp_client.c
/*************************************************************************************************************
* 文件名: udp_client.c
* 功能: uIP UDP客户端相关函数
* 作者: cp1300@139.com
* 创建时间: 2014-06-06
* 最后修改时间: 2014-06-06
* 详细: UDP客户端相关函数
*************************************************************************************************************/
#include "SYSTEM.h"
#include "uip.h"
#include <string.h>
#include <stdio.h>
#include "uIP_user.H"
#include "AppClient.H"
#include "udp_client.h"
static struct uip_udp_conn *myudp_conn;
u16 UDP_ClientPort = UDP_LOCAL_PORT; //UDP本地端口
UIP_USER udp_client; //UDP 客户端数据结构
/*************************************************************************************************************************
* 函数 : bool udp_client_reconnect(u8 IpAddr0,u8 IpAddr1,u8 IpAddr2,u8 IpAddr3, u16 ServerPort, u16 ClientPort)
* 功能 : 建立一个UDP客户端
* 参数 : IpAddr:UDP服务器IP地址;ServerPort:服务器端口;ClientPort:客户端本地端口
* 返回 : FALSE:失败;TRUE:成功
* 依赖 : uip
* 作者 : cp1300@139.com
* 时间 : 2014-06-06
* 最后修改时间 : 2014-06-06
* 说明 : 服务器必须指定端口,客户端端口为0则为随机端口
*************************************************************************************************************************/
bool udp_client_reconnect(u8 IpAddr0,u8 IpAddr1,u8 IpAddr2,u8 IpAddr3, u16 ServerPort, u16 ClientPort)
{
uip_ipaddr_t ipaddr;
uip_ipaddr(ipaddr, IpAddr0,IpAddr1,IpAddr2,IpAddr3); //UDP服务器IP地址
if(myudp_conn != NULL)
{
uip_udp_remove(myudp_conn); //如果连接已经建立,则删除之
}
myudp_conn = uip_udp_new(&ipaddr, htons(ServerPort), ClientPort);//建立到远程ipaddr
if(myudp_conn != NULL) //连接建立成功
{
udp_client.RxLen = 0;
udp_client.TxLen = 0;
UDP_ClientPort = HTONS(myudp_conn->lport); //本地端口
udp_client.ClientPort = UDP_ClientPort;
udp_client.ServerPort = HTONS(myudp_conn->rport);
uart_printf("UDP 建立成功!本地端口:%d 服务器端口:%d\r\n",udp_client.ClientPort, udp_client.ServerPort);
uip_udp_bind(myudp_conn, htons(UDP_ClientPort)); //绑定本地端口
return TRUE;
}
else//连接建立失败
{
UDP_ClientPort = 0; //本地端口
udp_client.ClientPort = 0;
udp_client.ServerPort = 0;
uart_printf("UDP 建立失败!\r\n");
return FALSE;
}
}
/*************************************************************************************************************************
* 函数 : void udp_client_appcall(void)
* 功能 : UDP 客户端应用回调函数
* 参数 : 无
* 返回 : 无
* 依赖 : uip
* 作者 : cp1300@139.com
* 时间 : 2014-06-04
* 最后修改时间 : 2014-06-05
* 说明 : 无
*************************************************************************************************************************/
void udp_client_appcall(void)
{
if (uip_newdata())
{
if(uip_datalen() > UIP_RX_BUFF_ZISE) uip_len = UIP_RX_BUFF_ZISE;//限制大小
memcpy(udp_client.RxBuff, uip_appdata, uip_len); //复制接收的数据到接收缓冲区
udp_client.RxLen = uip_len; //存储接收数据长度
}
//新数据到达,轮询,发送数据
if(udp_client.TxLen)
{
uip_send(udp_client.TxBuff, udp_client.TxLen); //发送UDP数据包
udp_client.TxLen = 0;
}
}
/*************************************************************************************************************************
* 函数 : void udp_SendDataPackage(u8 *pBuff, u16 len)
* 功能 : UDP用户发送外部调用接口
* 参数 : 无
* 返回 : 无
* 依赖 : uip
* 作者 : cp1300@139.com
* 时间 : 2014-06-04
* 最后修改时间 : 2014-06-05
* 说明 : 由底层调度器进行调度自动发送
*************************************************************************************************************************/
void udp_SendDataPackage(u8 *pBuff, u16 len)
{
if(len > UIP_TX_BUFF_ZISE) len = UIP_TX_BUFF_ZISE;
memcpy(udp_client.TxBuff, pBuff, len);
udp_client.TxLen = len;
}
/*************************************************************************************************************
* 文件名: udp_client.h
* 功能: uIP UDP客户端相关函数
* 作者: cp1300@139.com
* 创建时间: 2014-06-06
* 最后修改时间: 2014-06-06
* 详细: UDP客户端相关函数
*************************************************************************************************************/
#ifndef _UDP_CLIENT_H_
#define _UDP_CLIENT_H_
#include "tcp.h"
#include "uip.h"
#include "system.h"
#include "uIP_user.h"
extern u16 UDP_ClientPort; //UDP 客户端本地端口
extern UIP_USER udp_client; //UDP 客户端数据结构
bool udp_client_reconnect(u8 IpAddr0,u8 IpAddr1,u8 IpAddr2,u8 IpAddr3, u16 ServerPort, u16 ClientPort); //建立一个UDP客户端
void udp_client_appcall(void); //UDP 客户端应用回调函数
void udp_SendDataPackage(u8 *pBuff, u16 len); //UDP用户发送外部调用接口
#endif //_UDP_CLIENT_H_
测试线程
udp_server_connected(UDP_SERVER_PORT, 0); //新建UDP服务器,客户端任意端口
udp_client_reconnect(255,255,255,255,UDP_REMOTE_PORT,UDP_LOCAL_PORT); //广播方式连接服务器
while(1)
{
UIP_MutexPen(); //申请信号量
//UDP通信处理
if(udp_client.RxLen > 0)
{
uart_printf("UDP客户端\r\n");
uart_printf("服务器端口:%d\r\n",udp_client.ServerPort);
uart_printf("客户端端口:%d\r\n",udp_client.ClientPort);
uart_printf("UDP Server Rx(%dB):%s\r\n",udp_client.RxLen,(char*)udp_client.RxBuff);
udp_SendDataPackage(udp_client.RxBuff, udp_client.RxLen);
udp_client.RxLen = 0;
}
//UDP服务器数据处理
if(udp_server.RxLen > 0)
{
uart_printf("UDP服务器\r\n");
uart_printf("服务器端口:%d\r\n",udp_server.ServerPort);
uart_printf("客户端端口:%d\r\n",udp_server.ClientPort);
uart_printf("UDP Server Rx(%dB):%s\r\n",udp_server.RxLen,(char*)udp_server.RxBuff);
udp_ServerSendDataPackage(udp_server.RxBuff, udp_server.RxLen, udp_server.ClientPort);
udp_server.RxLen = 0;
}
UIP_MutexPost(); //释放信号量
if(isGetIP == FALSE) goto Udp_Reset; //掉线后重新初始化
OSTimeDlyHMSM(0,0,0,100);
}
}
需要修改uip_udp_new
添加一个简单的随机数产生本地随机端口
/*---------------------------------------------------------------------------*/
//注意,rport:需要htons(xxxx)
//lport:0系统随机端口;否则:指定端口,无需htons(),直接输入即可
#if UIP_UDP
struct uip_udp_conn *
uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport, u16 lport)
{
register struct uip_udp_conn *conn;
/* Find an unused local port. */
again:
if(lport == 0) //随机端口
{
//++lastport;
lastport = 1024+UIP_GetRandom()%3096+UIP_GetRandom()%1024;
// if(lastport >= 32000)
// {
// lastport = 4096;
// }
}
else lastport = lport; //指定端口
for(c = 0; c < UIP_UDP_CONNS; ++c) {
if(uip_udp_conns[c].lport == htons(lastport)) {
goto again;
}
}
测试截图
一般的调试软件的UDP服务器模式都不好用或者没有,我使用的是别人的一款上位机中的UDP广播搜索模式进行测试的.