目前移植了UDP客戶端模式,測試使用廣播地址.
//udp_client.c
/*************************************************************************************************************
?*?文件名: udp_client.c
?*?功能: uIP?UDP客戶端相關(guān)函數(shù)
?*?作者: cp1300@139.com
?*?創(chuàng)建時間: 2014-06-06
?*?最后修改時間: 2014-06-06
?*?詳細: UDP客戶端相關(guān)函數(shù)
*************************************************************************************************************/
#include?"SYSTEM.h"
#include?"uip.h"
#include#include #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?客戶端數(shù)據(jù)結(jié)構(gòu)
/*************************************************************************************************************************
*?函數(shù) : bool?udp_client_reconnect(u8?IpAddr0,u8?IpAddr1,u8?IpAddr2,u8?IpAddr3,?u16?ServerPort,?u16?ClientPort)
*?功能 : 建立一個UDP客戶端
*?參數(shù) : 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); //如果連接已經(jīng)建立,則刪除之
}
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?服務器端口:%drn",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?建立失敗!rn");
return?FALSE;
}
}
? ???
/*************************************************************************************************************************
*?函數(shù) : void?udp_client_appcall(void)
*?功能 : UDP?客戶端應用回調(diào)函數(shù)
*?參數(shù) : 無
*?返回 : 無
*?依賴 : 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); //復制接收的數(shù)據(jù)到接收緩沖區(qū)
udp_client.RxLen?=?uip_len; //存儲接收數(shù)據(jù)長度
????}
//新數(shù)據(jù)到達,輪詢,發(fā)送數(shù)據(jù)?
if(udp_client.TxLen)?
{
uip_send(udp_client.TxBuff,?udp_client.TxLen); //發(fā)送UDP數(shù)據(jù)包
udp_client.TxLen?=?0;
}
}
/*************************************************************************************************************************
*?函數(shù) : void?udp_SendDataPackage(u8?*pBuff,?u16?len)
*?功能 : UDP用戶發(fā)送外部調(diào)用接口
*?參數(shù) : 無
*?返回 : 無
*?依賴 : uip
*?作者 : cp1300@139.com
*?時間 : 2014-06-04
*?最后修改時間 :? 2014-06-05
*?說明 :? 由底層調(diào)度器進行調(diào)度自動發(fā)送
*************************************************************************************************************************/
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
/************************************************************************************************************* ?*?文件名: udp_client.h ?*?功能: uIP?UDP客戶端相關(guān)函數(shù) ?*?作者: cp1300@139.com ?*?創(chuàng)建時間: 2014-06-06 ?*?最后修改時間: 2014-06-06 ?*?詳細: UDP客戶端相關(guān)函數(shù) *************************************************************************************************************/ #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?客戶端數(shù)據(jù)結(jié)構(gòu) bool?udp_client_reconnect(u8?IpAddr0,u8?IpAddr1,u8?IpAddr2,u8?IpAddr3,?u16?ServerPort,?u16?ClientPort); //建立一個UDP客戶端 void?udp_client_appcall(void); //UDP?客戶端應用回調(diào)函數(shù) void?udp_SendDataPackage(u8?*pBuff,?u16?len); //UDP用戶發(fā)送外部調(diào)用接口 #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客戶端rn");
uart_printf("服務器端口:%drn",udp_client.ServerPort);
uart_printf("客戶端端口:%drn",udp_client.ClientPort);
uart_printf("UDP?Server?Rx(%dB):%srn",udp_client.RxLen,(char*)udp_client.RxBuff);
udp_SendDataPackage(udp_client.RxBuff,?udp_client.RxLen);
udp_client.RxLen?=?0;
}
//UDP服務器數(shù)據(jù)處理
if(udp_server.RxLen?>?0)
{
uart_printf("UDP服務器rn");
uart_printf("服務器端口:%drn",udp_server.ServerPort);
uart_printf("客戶端端口:%drn",udp_server.ClientPort);
uart_printf("UDP?Server?Rx(%dB):%srn",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
添加一個簡單的隨機數(shù)產(chǎn)生本地隨機端口
/*---------------------------------------------------------------------------*/
//注意,rport:需要htons(xxxx)
//lport:0系統(tǒng)隨機端口;否則:指定端口,無需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;
????}
??}
測試截圖
一般的調(diào)試軟件的UDP服務器模式都不好用或者沒有,我使用的是別人的一款上位機中的UDP廣播搜索模式進行測試的.





