LWIP裸機環境下實現TCP與UDP通信

  前面移植了LWIP,而且簡單的實用了DHCP的功能,今天來使用一下實際的數據通信的功能編程

  首先是實現TCP客戶端,我先上代碼緩存

#ifndef __TCP_CLIENT_H_
#define __TCP_CLIENT_H_
#include "network.h"



//鏈接狀態
enum tcp_client_states            
{
  ES_NONE = 0,            
  ES_RECEIVED,        //接收到了數據
  ES_CLOSING            //鏈接關閉
};

 //TCP服務器狀態
struct tcp_client_state
{
  u8_t state;
};

#define LWIP_CLIENT_BUF   200    //TCP連接緩存

extern u8 lwip_client_buf[LWIP_CLIENT_BUF];        //定義用來發送和接收數據的緩存

extern u8 lwip_tcp_client_flag;      //用於定義lwip tcp client狀態

//客戶端成功鏈接到遠程主機時調用
err_t Tcp_Client_Connect(void *arg,struct tcp_pcb *tpcb,err_t err);

//鏈接輪詢時將要調用的函數
err_t Tcp_Client_Poll(void *arg, struct tcp_pcb *tpcb);

//用於鏈接遠程主機
void Tcp_Client_Connect_Remotehost(void);

//客戶端接收到數據以後將要調用的函數
err_t Tcp_Client_Recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err);

//關閉鏈接
void Tcp_Client_Close(struct tcp_pcb *tpcb, struct tcp_client_state* ts);
    
//初始化TCP客戶端
void Tcp_Client_Init(void);

#endif
#include "tcp_client.h"


u8 lwip_tcp_client_flag;      //用於定義lwip tcp client狀態

//定義一個TCP的協議控制塊
struct tcp_pcb* tcp_client_pcb;
//連接的自動迴應信息
static const char* respond =  "tcp_client connect success\r\n";





u8 lwip_client_buf[LWIP_CLIENT_BUF];        //定義用來發送和接收數據的緩存



//客戶端成功鏈接到遠程主機時調用
err_t Tcp_Client_Connect(void *arg,struct tcp_pcb *tpcb,err_t err)
{
    struct tcp_client_state* ts;
    ts = arg;    
    ts->state =   ES_RECEIVED;        //能夠開始接收數據了
    lwip_tcp_client_flag |= LWIP_CONNECTED;        //標記鏈接成功了
    tcp_write(tpcb,respond,strlen(respond),1);  //迴應信息    
    return ERR_OK;
}


//鏈接輪詢時將要調用的函數
err_t Tcp_Client_Poll(void *arg, struct tcp_pcb *tpcb)
{
    err_t ret_err;
    struct tcp_client_state* ts;
    ts = arg;
//    lwip_log("tcp_client_polling!\r\n");
    if(ts!=NULL)//鏈接處於空閒能夠發送數據
    {        
        if((lwip_tcp_client_flag&LWIP_SEND_DATA)==LWIP_SEND_DATA)
        {
            tcp_write(tpcb,lwip_client_buf,strlen((char *)lwip_client_buf),1);//發送數據
            lwip_tcp_client_flag &=~LWIP_SEND_DATA;        //清除發送數據的標誌
        }
    }
    else
    {
        tcp_abort(tpcb);
        ret_err = ERR_ABRT;
    }
    return ret_err;
}



//用於鏈接遠程主機
void Tcp_Client_Connect_Remotehost(void)
{
    //記住若是此處須要頻繁重連的時候記得先關閉已經申請的tcb
    //最好將tcb換成全局變量
//    Tcp_Client_Close();
    Tcp_Client_Init();
}




//客戶端接收到數據以後將要調用的函數
err_t Tcp_Client_Recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
    err_t ret_err;
    struct tcp_client_state* ts;
    ts = arg;            //TCP PCB狀態
    if(p==NULL)
    {    
        ts->state = ES_CLOSING;        //鏈接關閉了
        Tcp_Client_Close(tpcb,ts);
        lwip_tcp_client_flag &=~ LWIP_CONNECTED;    //清除鏈接標誌
    }
    else if(err!=ERR_OK)
    {    //位置錯誤釋放pbuf
        if(p!=NULL)
        {
            pbuf_free(p);
        }
        ret_err = err;        //獲得錯誤
    }
    else if(ts->state==ES_RECEIVED)
    {//鏈接收到了新的數據

        //    printf("服務器新接收的數據:%s\r\n",p->payload);
        if((p->tot_len)>=LWIP_CLIENT_BUF)
        {         //若是收的的數據大於緩存
            ((char*)p->payload)[199] = 0;             
            memcpy(lwip_client_buf,p->payload,200);
        }
        else
        {                
            memcpy(lwip_client_buf,p->payload,p->tot_len);
            lwip_client_buf[p->tot_len] = 0;                    
        }
        lwip_tcp_client_flag |= LWIP_NEW_DATA;        //收到了新的數據
        tcp_recved(tpcb, p->tot_len);        //用於獲取接收數據的長度,    表示能夠獲取更多的數據            
        pbuf_free(p);    //釋放內存
        ret_err = ERR_OK;
    }
    else if(ts->state==ES_CLOSING)//服務器關閉了
    {    
        tcp_recved(tpcb, p->tot_len);        //遠程端口關閉兩次,垃圾數據
        pbuf_free(p);
        ret_err = ERR_OK;
    }
    else
    {                                        //其餘未知狀態
        tcp_recved(tpcb, p->tot_len);
        pbuf_free(p);
        ret_err = ERR_OK;
    }
    return ret_err;
    
}




//關閉鏈接
void Tcp_Client_Close(struct tcp_pcb *tpcb, struct tcp_client_state* ts)
{

    tcp_arg(tcp_client_pcb, NULL);              
    tcp_recv(tcp_client_pcb, NULL);
    tcp_poll(tcp_client_pcb, NULL, 0); 
    if(ts!=NULL)
    {
        mem_free(ts);
    }
    tcp_close(tpcb);
}




//指定鏈接的客戶端爲1300端口
#define TCP_CLIENT_PORT  1300

//初始化TCP客戶端
void Tcp_Client_Init(void)
{
    struct tcp_client_state* ts;
    ip_addr_t ipaddr;
    IP4_ADDR(&ipaddr, 192, 168, 1, 101);      
    
    tcp_client_pcb = tcp_new();                //新建一個PCB
    if(tcp_client_pcb!=NULL)
    {    
        ts = mem_malloc(sizeof(struct tcp_client_state));     //申請內存
        tcp_arg(tcp_client_pcb, ts);                  //將程序的協議控制塊的狀態傳遞給多有的回調函數
        //設定TCP的回調函數
        tcp_connect(tcp_client_pcb,&ipaddr,TCP_CLIENT_PORT,Tcp_Client_Connect);
        tcp_recv(tcp_client_pcb, Tcp_Client_Recv);    //指定鏈接接收到新的數據以後將要調用的回調函數
        tcp_poll(tcp_client_pcb, Tcp_Client_Poll, 0); //指定輪詢時將要調用的回調函數
    }
}

    咱們能夠看到,在tcp客戶端初始化的時候咱們使用了回調函數技術將接收數據和輪詢數據的函數添加到了網絡的底層輪轉中,還要指定連接的端口和ip,可是不須要指定本地端口
同時,咱們還在在程序主循環中不停地處理網絡事件(由於沒有操做系統)服務器

//LWIP查詢
void LWIP_Polling(void)
{
    if(timer_expired(&input_time,5)) //接收包,週期處理函數
    {
        ethernetif_input(&enc28j60_netif); 
    }
    if(timer_expired(&last_tcp_time,TCP_TMR_INTERVAL/CLOCKTICKS_PER_MS))//TCP處理定時器處理函數
    {
        tcp_tmr();
    }
    if(timer_expired(&last_arp_time,ARP_TMR_INTERVAL/CLOCKTICKS_PER_MS))//ARP處理定時器
    {
        etharp_tmr();
    }
    if(timer_expired(&last_ipreass_time,IP_TMR_INTERVAL/CLOCKTICKS_PER_MS))//IP從新組裝定時器
    { 
        ip_reass_tmr();
    }                                   
}

這樣,完整的TCP通信鏈路就能建成了,數據的使用這樣網絡

if((lwip_tcp_client_flag&LWIP_CONNECTED)==LWIP_CONNECTED)
        {
            LCD_ShowString(0,24,240,320,(u8*)"TCP CLIENT Connect                     ",LCD_BLACK);
            if(keyValue == KEY_RIGHT)
            {
                t_client_cnt++;
                sprintf((char*)lwip_client_buf,"tcp_client send %d\r\n",t_client_cnt);    
                LCD_ShowString(18,48,240,320,(u8*)lwip_client_buf,LCD_BLACK);//顯示當前發送數據
                lwip_tcp_client_flag |= LWIP_SEND_DATA;            //標記有數據須要發送
                keyValue = 0;
            }
        }
        else
        {
//            Tcp_Client_Connect_Remotehost();//沒有鏈接上,此時處於TCP客戶端模式,則嘗試從新鏈接
        }
        
        if((lwip_tcp_client_flag&LWIP_NEW_DATA)==LWIP_NEW_DATA)
        {
            LCD_ShowString(18,36,240,320,(u8*)lwip_client_buf,LCD_BLACK);
            lwip_tcp_client_flag &=~LWIP_NEW_DATA;        //清除接受數據的標誌
        }


同理,TCP服務器的流程也差很少,可是多了一個東西,tcp服務器要監聽本地某一個特定端口,使用以下tcp

#include "tcp_service.h"

struct tcp_pcb* tcp_server_pcb;//定義一個TCP的協議控制塊

static const char* respond =  "tcp_service connect ok!\r\n";

u8 lwip_tcp_service_flag;      //用於定義lwip tcp client狀態

u8 lwip_service_buf[LWIP_SERCER_BUF];        //定義用來發送和接收數據的緩存

//初始化LWIP服務器
void Init_TCP_Server(void)
{
        err_t err;                //LWIP錯誤信息
        tcp_server_pcb = tcp_new();        //新建一個TCP協議控制塊
        if(tcp_server_pcb!=NULL)
        {
                err = tcp_bind(tcp_server_pcb,IP_ADDR_ANY,TCP_SERVER_PORT);//綁定本地全部IP地址和端口號 做爲服務器不須要知道客戶端的IP
                if(err==ERR_OK)//成功綁定
                {
                    tcp_server_pcb = tcp_listen(tcp_server_pcb);    //開始監聽端口
                    tcp_accept(tcp_server_pcb,Tcp_Server_Accept); //指定監聽狀態的鏈接聯通以後將要調用的回調函數
                }
        }
    

}

//服務器鏈接成功後將要調用的函數
err_t Tcp_Server_Accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{
    err_t ret_err;
    struct tcp_server_state* ts;

    ts = mem_malloc(sizeof(struct tcp_server_state));     //申請內存
    if(ts!=NULL)
    {
        ts->state = ES_SERVER_RECEIVED;                            //能夠接收數據了
        lwip_tcp_service_flag |= LWIP_CONNECTED;                //已經鏈接上了
        tcp_write(newpcb,respond,strlen(respond),1);  //迴應信息

        tcp_arg(newpcb, ts);                  //將程序的協議控制塊的狀態傳遞給多有的回調函數

        tcp_recv(newpcb, Tcp_Server_Recv);    //指定鏈接接收到新的數據以後將要調用的回調函數
        tcp_err(newpcb, Tcp_Server_Error);    //指定鏈接出錯將要調用的函數
        tcp_poll(newpcb, Tcp_Server_Poll, 0); //指定輪詢時將要調用的回調函數
        ret_err = ERR_OK;
    }
    else
    {
        ret_err = ERR_MEM;
    }
    return ret_err;
    
}


//鏈接輪詢時將要調用的函數
err_t Tcp_Server_Poll(void *arg, struct tcp_pcb *tpcb)
{
    err_t ret_err;
    struct tcp_server_state* ts;
    ts = arg;
    if(ts!=NULL)
    {        //鏈接處於空閒能夠發送數據
        if((lwip_tcp_service_flag&LWIP_SEND_DATA)==LWIP_SEND_DATA)
        {
            tcp_write(tpcb,lwip_service_buf,strlen((char *)lwip_service_buf),1);//發送數據
            lwip_tcp_service_flag &=~LWIP_SEND_DATA;        //清除發送數據的標誌
        }
    }
    else
    {
        tcp_abort(tpcb);
        ret_err = ERR_ABRT;
    }
    return ret_err;
}


//服務器接收到數據以後將要調用的函數
err_t Tcp_Server_Recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
    err_t ret_err;
    struct tcp_server_state* ts;

    ts = arg;            //TCP PCB狀態
    if(p==NULL)
    {    
        ts->state = ES_SERVER_CLOSING;        //鏈接關閉了
        Tcp_Server_Close(tpcb,ts);
        lwip_tcp_service_flag &=~ LWIP_CONNECTED;    //清除鏈接標誌
    }
    else if(err!=ERR_OK)
    {    //未知錯誤,釋放pbuf
        if(p!=NULL)
        {
            pbuf_free(p);
        }
        ret_err = err;        //獲得錯誤
    }
    else if(ts->state==ES_SERVER_RECEIVED)
    {//鏈接收到了新的數據
        if((p->tot_len)>=LWIP_SERCER_BUF)
        {         //若是收的的數據大於緩存
            ((char*)p->payload)[199] = 0;             
            memcpy(lwip_service_buf,p->payload,200);
        }
        else
        {                
            memcpy(lwip_service_buf,p->payload,p->tot_len);
            lwip_service_buf[p->tot_len] = 0;                    
        }

        lwip_tcp_service_flag |= LWIP_NEW_DATA;        //收到了新的數據

        tcp_recved(tpcb, p->tot_len);        //用於獲取接收數據的長度,    通知LWIP已經讀取了數據,能夠獲取更多的數據
        pbuf_free(p);    //釋放內存
        ret_err = ERR_OK;
    }
    else if(ts->state==ES_SERVER_CLOSING)
    {    //服務器關閉了
        tcp_recved(tpcb, p->tot_len);        //遠程端口關閉兩次,垃圾數據
        pbuf_free(p);
        ret_err = ERR_OK;
    }
    else
    {                                        //其餘未知狀態
        tcp_recved(tpcb, p->tot_len);
        pbuf_free(p);
        ret_err = ERR_OK;
    }
    return ret_err;
    
}

//鏈接出錯將要調用的函數
void Tcp_Server_Error(void *arg,err_t err)
{
    struct tcp_server_state* ts;
    ts = arg;
    if(ts!=NULL)
    {
        mem_free(ts);
    }
}


//關閉鏈接
void Tcp_Server_Close(struct tcp_pcb *tpcb, struct tcp_server_state* ts)
{
    if(ts!=NULL)
    {
        mem_free(ts);
    }
    tcp_close(tpcb);
}

能夠看到上面的代碼多了一個bind的過程函數

剩下的就是udp通信了,在以前tcp的源碼裏面能看到,發送數據的時候不須要專門去作發送函數,指定一個標誌位就好了,在輪轉的時候程序會自動把數據發送出去,當使用UDP的時候就不行了,由於TCP是面向連接的,而UDP自己就是無鏈接的,UDP的是使用源碼以下spa

#include "udp_send.h"

//該文件便可以接受也能夠發送數據
//都是用1500端口進行操做

u8 lwip_udp_send_buf[LWIP_UDP_SEND_BUF];        //定義用來發送和接收數據的緩存
u8 lwip_udp_send_flag;      //用於定義lwip tcp client狀態

struct udp_pcb* udp_client_pcb;//定義一個UDP的協議控制塊
struct pbuf * ubuf_client;


//接收到數據包將要調用的函數
void udp_client_rev(void* arg,struct udp_pcb* upcb,struct pbuf* p,struct ip_addr*addr ,u16_t port)
{
    if(p!=NULL)
    {
        if((p->tot_len)>=LWIP_UDP_SEND_BUF)
        {         //若是收的的數據大於緩存
            ((char*)p->payload)[199] = 0;             
            memcpy(lwip_udp_send_buf,p->payload,200);
        }
        else
        {                
            memcpy(lwip_udp_send_buf,p->payload,p->tot_len);
            lwip_udp_send_buf[p->tot_len] = 0;                    
        }
        lwip_udp_send_flag |= LWIP_NEW_DATA;        //收到了新的數據
        pbuf_free(p);
    } 
}

//發送數據
void udp_client_send_data(void)
{
    err_t err;
    if((lwip_udp_send_flag&LWIP_SEND_DATA)==LWIP_SEND_DATA)
    {
        ubuf_client = pbuf_alloc(PBUF_TRANSPORT, strlen((char *)lwip_udp_send_buf), PBUF_RAM); //爲發送包分配內存
        ubuf_client->payload = lwip_udp_send_buf;
        err=udp_send(udp_client_pcb,ubuf_client);//發送數據
        if(err!=ERR_OK)
        {
            //lwip_log("UDP SERVER發送數據失敗!");
        }
        lwip_udp_send_flag &=~LWIP_SEND_DATA;        //清除發送數據的標誌
        pbuf_free(ubuf_client);
    }
}

//初始化UDP客戶端
void Init_UDP_Client(void)
{
    //struct ip_addr* ipaddr;
    ip_addr_t ipaddr;
    IP4_ADDR(&ipaddr, 192, 168, 1, 101);          //設置本地ip地址
    udp_client_pcb = udp_new();    //新建一個UDP協議控制塊
    if(udp_client_pcb!=NULL)
    {
        udp_bind(udp_client_pcb,IP_ADDR_ANY,UDP_CLIENT_PORT);        //
        udp_connect(udp_client_pcb,&ipaddr,UDP_CLIENT_PORT);  //設置鏈接到遠程主機
        udp_recv(udp_client_pcb,udp_client_rev,NULL);                //指定收到數據包時的回調函數
    }
}

    這是一個UDP的客戶端,在初始化的時候指明瞭目的主機的地址和端口號,鏈接到目的主機上操作系統

  接下來是一個UDP的服務器.net

#include "udp_recv.h"


struct udp_pcb* udp_server_pcb;//定義一個UDP的協議控制塊
struct pbuf * ubuf;

u8 lwip_udp_recv_buf[LWIP_UDP_RECV_BUF];        //定義用來發送和接收數據的緩存
u8 lwip_udp_recv_flag;                          //用於定義lwip tcp client狀態


//接收到數據包將要調用的函數
void Udp_Server_Recv(void* arg,struct udp_pcb* upcb,struct pbuf* p,struct ip_addr*addr ,u16_t port)
{
    if(p!=NULL)
    {
        if((p->tot_len)>=LWIP_UDP_RECV_BUF)
        {         //若是收的的數據大於緩存
            ((char*)p->payload)[199] = 0;             
            memcpy(lwip_udp_recv_buf,p->payload,200);
        }
        else
        {                
            memcpy(lwip_udp_recv_buf,p->payload,p->tot_len);
            lwip_udp_recv_buf[p->tot_len] = 0;                    
        }
        lwip_udp_recv_flag |= LWIP_NEW_DATA;        //收到了新的數據
        udp_server_pcb->remote_ip = *addr; //記錄遠程主機的IP和端口號
        udp_server_pcb->remote_port = port;
        pbuf_free(p);
    } 
}

//發送數據
void Udp_Server_Send_Data(void)
{
    err_t err;
    if((lwip_udp_recv_flag&LWIP_SEND_DATA)==LWIP_SEND_DATA)
    {
        ubuf = pbuf_alloc(PBUF_TRANSPORT, strlen((char *)lwip_udp_recv_buf), PBUF_RAM); 
        ubuf->payload = lwip_udp_recv_buf;
        err=udp_send(udp_server_pcb,ubuf);//發送數據
        if(err!=ERR_OK)
        {
            //do something
        }
        lwip_udp_recv_flag &=~LWIP_SEND_DATA;        //清除發送數據的標誌
        pbuf_free(ubuf);
    }
}



//初始化UDP服務器
void Init_UDP_Server(void)
{
    udp_server_pcb = udp_new();    //新建一個UDP協議控制塊
    if(udp_server_pcb!=NULL)
    {
        udp_bind(udp_server_pcb,IP_ADDR_ANY,UDP_RECV_PORT);            //監聽一個UDP端口
        udp_recv(udp_server_pcb,Udp_Server_Recv,NULL);                //指定收到數據包時的回調函數
    }
}

能夠看到,UDP的服務器在使用的時候沒有主動去鏈接那個IP,他只是本身綁定了本身的某個端口,算是客戶端和服務器編程的兩種差別code

給一個使用文件

#include "mainInclude.h"

#include "lwip/init.h"
#include "lwip/ip.h"
#include "lwip/dhcp.h"
#include "lwip/tcp_impl.h"
#include "lwip/ip_frag.h"
#include "lwip/dns.h"
#include "netif/etharp.h"
#include "netif/ethernetif.h"
#include "arch/sys_arch.h"

#define CLOCKTICKS_PER_MS 10    //定義時鐘節拍

static ip_addr_t ipaddr, netmask, gw;     //定義IP地址
struct netif enc28j60_netif;              //定義網絡接口
u32_t input_time;
u32_t last_arp_time;            
u32_t last_tcp_time;    
u32_t last_ipreass_time;

u32_t last_dhcp_fine_time;            
u32_t last_dhcp_coarse_time;  
u32 dhcp_ip=0;

//LWIP查詢
void LWIP_Polling(void)
{
    if(timer_expired(&input_time,5)) //接收包,週期處理函數
    {
        ethernetif_input(&enc28j60_netif); 
    }
    if(timer_expired(&last_tcp_time,TCP_TMR_INTERVAL/CLOCKTICKS_PER_MS))//TCP處理定時器處理函數
    {
        tcp_tmr();
    }
    if(timer_expired(&last_arp_time,ARP_TMR_INTERVAL/CLOCKTICKS_PER_MS))//ARP處理定時器
    {
        etharp_tmr();
    }
    if(timer_expired(&last_ipreass_time,IP_TMR_INTERVAL/CLOCKTICKS_PER_MS))//IP從新組裝定時器
    { 
        ip_reass_tmr();
    }                                   
}

int main(void)
{
    u8 t_client_cnt = 0;
    u8 t_server_cnt = 0;
    u8 t_send_cnt = 0;
    u8 t_recv_cnt = 0;
    NVIC_Group_Init();//系統默認中斷分組
    Debug_Serial_Init(115200);
    Delay_Init();
    Led_Init();
    Key_Exti_Init();
    LCD_Init();
    LCD_Clear(LCD_BLACK);
    
    IP4_ADDR(&ipaddr, 192, 168, 1, 110);          //設置本地ip地址
    IP4_ADDR(&gw, 192, 168, 1, 1);            //網關
    IP4_ADDR(&netmask, 255, 255, 255, 0);        //子網掩碼    
    
    //初始化LWIP定時器
    init_lwip_timer();  
    //初始化LWIP協議棧,執行檢查用戶全部可配置的值,初始化全部的模塊
    lwip_init();
    
    //添加網絡接口
    while((netif_add(&enc28j60_netif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &ethernet_input)==NULL))
    {
        LCD_ShowString(0,0,240,320,(u8*)"ENC28J60 Init Failed             ",LCD_BLACK);
        Delay_Ms(200);
        LCD_ShowString(0,0,240,320,(u8*)"                                 ",LCD_BLACK);
        Delay_Ms(200);
    }
    LCD_ShowString(0,0,240,320,(u8*)"ENC28J60 Init OK                     ",LCD_BLACK);
    //註冊默認的網絡接口
    netif_set_default(&enc28j60_netif);
    //創建網絡接口用於處理通訊
    netif_set_up(&enc28j60_netif); 
    
    Tcp_Client_Init();//初始化tcp客戶端
    
    LCD_ShowString(0,12,240,320,(u8*)"TCP CLIENT INIT                      ",LCD_BLACK);
    LCD_ShowString(0,24,240,320,(u8*)"TCP CLIENT Disconnect                ",LCD_BLACK);
    LCD_ShowString(0,36,240,320,(u8*)"RX:                                  ",LCD_BLACK);
    LCD_ShowString(0,48,240,320,(u8*)"TX:                                  ",LCD_BLACK);
    
    Init_TCP_Server();
    LCD_ShowString(0,60,240,320,(u8*)"TCP SERVER INIT                      ",LCD_BLACK);
    LCD_ShowString(0,72,240,320,(u8*)"TCP SERVER Disconnect                ",LCD_BLACK);
    LCD_ShowString(0,84,240,320,(u8*)"RX:                                  ",LCD_BLACK);
    LCD_ShowString(0,96,240,320,(u8*)"TX:                                  ",LCD_BLACK);
    
    Init_UDP_Client();
    LCD_ShowString(0,108,240,320,(u8*)"UDP SEND INIT                        ",LCD_BLACK);
    LCD_ShowString(0,120,240,320,(u8*)"RX:                                  ",LCD_BLACK);
    LCD_ShowString(0,132,240,320,(u8*)"TX:                                  ",LCD_BLACK);
    
    Init_UDP_Server();//初始化UDP接收端
    LCD_ShowString(0,144,240,320,(u8*)"UDP RECV INIT                        ",LCD_BLACK);
    LCD_ShowString(0,156,240,320,(u8*)"RX:                                  ",LCD_BLACK);
    LCD_ShowString(0,168,240,320,(u8*)"TX:                                  ",LCD_BLACK);
    
    
    while(1)
    {
        LWIP_Polling();
        if((lwip_tcp_client_flag&LWIP_CONNECTED)==LWIP_CONNECTED)
        {
            LCD_ShowString(0,24,240,320,(u8*)"TCP CLIENT Connect                     ",LCD_BLACK);
            if(keyValue == KEY_RIGHT)
            {
                t_client_cnt++;
                sprintf((char*)lwip_client_buf,"tcp_client send %d\r\n",t_client_cnt);    
                LCD_ShowString(18,48,240,320,(u8*)lwip_client_buf,LCD_BLACK);//顯示當前發送數據
                lwip_tcp_client_flag |= LWIP_SEND_DATA;            //標記有數據須要發送
                keyValue = 0;
            }
        }
        else
        {
//            Tcp_Client_Connect_Remotehost();//沒有鏈接上,此時處於TCP客戶端模式,則嘗試從新鏈接
        }
        
        if((lwip_tcp_client_flag&LWIP_NEW_DATA)==LWIP_NEW_DATA)
        {
            LCD_ShowString(18,36,240,320,(u8*)lwip_client_buf,LCD_BLACK);
            lwip_tcp_client_flag &=~LWIP_NEW_DATA;        //清除接受數據的標誌
        }
        
        
        if((lwip_tcp_service_flag&LWIP_CONNECTED)==LWIP_CONNECTED)
        {
            LCD_ShowString(0,72,240,320,(u8*)"TCP SERVER Connect                     ",LCD_BLACK);
            if(keyValue == KEY_LEFT)
            {
                t_server_cnt++;
                sprintf((char*)lwip_service_buf,"tcp_service send %d\r\n",t_server_cnt);    
                LCD_ShowString(18,96,240,320,(u8*)lwip_service_buf,LCD_BLACK);//顯示當前發送數據
                lwip_tcp_service_flag |= LWIP_SEND_DATA;            //標記有數據須要發送
                keyValue = 0;
            }
        }
        if((lwip_tcp_service_flag&LWIP_NEW_DATA)==LWIP_NEW_DATA)
        {
            LCD_ShowString(18,84,240,320,(u8*)lwip_service_buf,LCD_BLACK);
            lwip_tcp_service_flag &=~LWIP_NEW_DATA;        //清除接受數據的標誌
        }
        
        if(keyValue == KEY_UP)
        {
            t_send_cnt++;
            sprintf((char*)lwip_udp_send_buf,"udp_send send %d\r\n",t_send_cnt);    
            LCD_ShowString(18,132,240,320,(u8*)lwip_udp_send_buf,LCD_BLACK);//顯示當前發送數據
            lwip_udp_send_flag |= LWIP_SEND_DATA;            //標記有數據須要發送
            keyValue = 0;
            udp_client_send_data();
        }
        
        if((lwip_udp_send_flag&LWIP_NEW_DATA)==LWIP_NEW_DATA)
        {
            LCD_ShowString(18,120,240,320,(u8*)lwip_udp_send_buf,LCD_BLACK);
            lwip_udp_send_flag &=~LWIP_NEW_DATA;        //清除接受數據的標誌
        }
        
        if(keyValue == KEY_DOWN)
        {
            t_recv_cnt++;
            sprintf((char*)lwip_udp_recv_buf,"udp_recv send %d\r\n",t_send_cnt);    
            LCD_ShowString(18,168,240,320,(u8*)lwip_udp_recv_buf,LCD_BLACK);//顯示當前發送數據
            lwip_udp_recv_flag |= LWIP_SEND_DATA;            //標記有數據須要發送
            keyValue = 0;
            Udp_Server_Send_Data();
        }
        
        if((lwip_udp_recv_flag&LWIP_NEW_DATA)==LWIP_NEW_DATA)
        {
            LCD_ShowString(18,156,240,320,(u8*)lwip_udp_recv_buf,LCD_BLACK);
            lwip_udp_recv_flag &=~LWIP_NEW_DATA;        //清除接受數據的標誌
        }
        
        Delay_Ms(1);
    }
}


void USB_LP_CAN1_RX0_IRQHandler(void)
{

}

void USBWakeUp_IRQHandler(void)
{
//    EXTI->PR|=1<<18;//清除USB喚醒中斷掛起位
}


完整的工程路徑以下

http://download.csdn.net/detail/dengrengong/8555627
相關文章
相關標籤/搜索