STM32移植LWIP之客户端与服务端的数据传输

服务端:

 1 //tcp_server_demo.h
 2 
 3 #ifndef __TCP_SERVER_DEMO_H
 4 #define __TCP_SERVER_DEMO_H
 5 #include "sys.h"
 6 #include "includes.h"       
 7 
 8  
 9 #define TCP_SERVER_RX_BUFSIZE    1460        //定义tcp server最大接收数据长度
10 #define TCP_SERVER_PORT            8087    //定义tcp server的端口
11 #define LWIP_SEND_DATA            0X80    //定义有数据发送
12 
13 extern u8 tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE];    //TCP客户端接收数据缓冲区
14 extern u8 tcp_server_flag;            //TCP服务器数据发送标志位
15 extern u8 recflag;
16 
17 INT8U tcp_server_init(void);        //TCP服务器初始化(创建TCP服务器线程)
18 #endif
  1 //tcp_server_demo.c
  2 
  3 #include "tcp_server_demo.h"
  4 #include "lwip/opt.h"
  5 #include "lwip_comm.h"
  6 #include "led.h"
  7 #include "lwip/lwip_sys.h"
  8 #include "lwip/api.h"
  9 #include "lcd.h"   
 10 #include "malloc.h" 
 11 #include "recorder.h"
 12 
 13 u8 tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE];                   //TCP客户端接收数据缓冲区
 14 u8 *tcp_server_sendbuf;
 15 u8 recflag=0;
 16 
 17 
 18 u8 receive_flag = 0;
 19 
 20 
 21 
 22 //TCP客户端任务   任务优先级最高!
 23 #define TCPSERVER_PRIO        6
 24 //任务堆栈大小
 25 #define TCPSERVER_STK_SIZE    300
 26 //任务堆栈
 27 OS_STK TCPSERVER_TASK_STK[TCPSERVER_STK_SIZE];
 28 
 29 
 30 
 31 /*服务器线程任务*/
 32 void my_tcp_server_thread(void *arg)
 33 {
 34     OS_CPU_SR cpu_sr; 
 35     
 36     struct pbuf *q;                                            //创建pbuf 数据包 用于接收数据
 37     u32 data_len = 0;                                          //已经储存的数据长度
 38     err_t err,recv_err;                                        //创建异常标志
 39     u8 remot_addr[4];                                          //创建一个客户机IP存储数组
 40     struct netconn *conn, *newconn;                            //netconn任务块 LWIP会根据TCP还是UDP自动分配合适的消息邮箱
 41     static ip_addr_t  ipaddr;                                  //创建一个存取ip地址的结构体    
 42     static u16_t             port;                                    //端口号
 43   u8 i;
 44     u8 re=0;
 45     tcp_server_sendbuf=mymalloc(SRAMEX,SAI_RX_DMA_BUF_SIZE);
 46     
 47     for(i=0;i<SAI_RX_FIFO_SIZE;i++)
 48     {
 49         sairecfifobuf2[i]=mymalloc(SRAMEX,SAI_RX_DMA_BUF_SIZE);//SAI接收FIFO内存申请
 50         if(sairecfifobuf2[i]==NULL)break;            //申请失败
 51     }
 52     if(!tcp_server_sendbuf||i!=SAI_RX_FIFO_SIZE) re=1;
 53     while(re);
 54     LWIP_UNUSED_ARG(arg);                                      //让LWIP知道这个参数没使用
 55     
 56     conn = netconn_new(NETCONN_TCP);                           //创建一个新TCP链接
 57     netconn_bind(conn,IP_ADDR_ANY,TCP_SERVER_PORT);            //绑定端口 8087号端口
 58     netconn_listen(conn);                                           //将conn置为监听状态
 59     conn->recv_timeout = 10;                                     //禁止阻塞线程 等待10ms  如果不等待,由于netconn_recv函数的使用 会阻塞线程
 60     while(1)
 61     {
 62         err = netconn_accept(conn,&newconn);                     //获得一个新连接
 63         if(err==ERR_OK)
 64         {
 65             newconn->recv_timeout = 10;                            //获取连接成功 newconn禁止阻塞线程 等待10ms
 66             
 67             struct netbuf *recvbuf;                                //创建一个netbuf格式的recvbuf 因为LWIP接收到数据包后会将数据封装在一个 netbuf 中等待应用程序处理
 68             
 69             netconn_getaddr(newconn,&ipaddr,&port,0);              //获取newconn连接的 客户机IP地址和端口号 并存在ipaddr和port中
 70             
 71             remot_addr[3] = (uint8_t)(ipaddr.addr >> 24);          //远端ip复制到remot_addr
 72             remot_addr[2] = (uint8_t)(ipaddr.addr>> 16);
 73             remot_addr[1] = (uint8_t)(ipaddr.addr >> 8);
 74             remot_addr[0] = (uint8_t)(ipaddr.addr);
 75             
 76             u8 *tbuf;                                              //使用LCD需要
 77             tbuf=mymalloc(SRAMIN,200);                               //申请内存
 78             POINT_COLOR = BLUE; 
 79             sprintf((char*)tbuf,"Client IP:%d.%d.%d.%d",remot_addr[0],remot_addr[1],remot_addr[2],remot_addr[3]);   //显示客户端IP
 80             LCD_ShowString(30,170,210,16,16,tbuf);
 81             POINT_COLOR = RED; 
 82             sprintf((char*)tbuf,"Local Port:%d",port);            //客户端端口号
 83             LCD_ShowString(30,190,210,16,16,tbuf);
 84             myfree(SRAMIN,tbuf);                                   //一定要释放内存否则会卡死
 85             while(1)
 86             {
 87                 
 88                 //数据发送函数
 89              //数据发送完毕后终止循环,一定使用NOCOPY模式!!!
 90 
 91                     wav_buffill(tcp_server_sendbuf);        //将发送FIFO中的数据填充到tcp_server_sendbuf中
 92                     while(netconn_write(newconn,tcp_server_sendbuf,1460,NETCONN_NOCOPY));  //将tcp_server_sendbuf中的数据发送出去
 93                     OSTimeDlyHMSM(0,0,0,20);
 94 
 95                 
 96                 
 97                 //OSTimeDlyHMSM(0,0,0,100);                               //系统延时50ms
 98                 
 99                 //数据接收函数
100             if((recv_err =netconn_recv(newconn,&recvbuf) ) == ERR_OK)   //判断是否收到数据
101             {
102                     OS_ENTER_CRITICAL();                                    //关中断
103                     
104                     memset(tcp_server_recvbuf,0,TCP_SERVER_RX_BUFSIZE);     //数据接收缓冲区清零
105                     
106                     for(q = recvbuf->p;q!=NULL;q=q->next)                   //遍历完整个pbuf链表
107                     {
108                         
109                         
110                         if(q->len > (TCP_SERVER_RX_BUFSIZE-data_len))         //判断要拷贝到TCP_SERVER_RX_BUFSIZE中的数据是否大于TCP_SERVER_RX_BUFSIZE的剩余空间,如果大于的话就只拷贝TCP_SERVER_RX_BUFSIZE中剩余长度的数据
111                             memcpy(tcp_server_recvbuf+data_len,q->payload,(TCP_SERVER_RX_BUFSIZE-data_len));//拷贝数据
112                         else 
113                             memcpy(tcp_server_recvbuf+data_len,q->payload,q->len);
114                         
115                         data_len += q->len; 
116                         
117                         if(data_len > TCP_SERVER_RX_BUFSIZE) 
118                             break;                                             //超出TCP客户端接收数组,跳出    
119                     }
120                     rec_sai_fifo_write2(tcp_server_recvbuf);    //将接收buf中的数据写入接收FIFO中
121                     recflag++;     
122                     
123                     OS_EXIT_CRITICAL();                                     //开中断
124                     data_len = 0;                                                                                                    //复制完成后data_len要清零
125                     netbuf_delete(recvbuf);                                 //删除recvbuf空间 否则会内存泄露
126                 }
127             
128                 
129                 else if(recv_err == ERR_CLSD)                             //如果收到关闭连接的通知
130                 {
131                     netconn_close(newconn);                                 //关闭newconn服务端
132                   netconn_delete(newconn);                                //删除服务端 否则会内存泄露
133                     LCD_ShowString(30,170,210,16,16,"                                    ");
134                     LCD_ShowString(30,190,210,16,16,"Connect closed                      ");
135                     break;
136                 }        
137             }
138         }
139     }
140 }
141 
142 
143 
144 
145 
146 //创建TCP服务器线程
147 //返回值:0 TCP服务器创建成功
148 //        其他 TCP服务器创建失败
149 INT8U tcp_server_init(void)
150 {
151     INT8U res;
152     OS_CPU_SR cpu_sr;
153     
154     OS_ENTER_CRITICAL();    //关中断
155     res = OSTaskCreate(my_tcp_server_thread,(void*)0,(OS_STK*)&TCPSERVER_TASK_STK[TCPSERVER_STK_SIZE-1],TCPSERVER_PRIO); //创建TCP服务器线程
156     OS_EXIT_CRITICAL();        //开中断
157     
158     return res;
159 }

客户端:

 1 //tcp_client_demo.h
 2 
 3 #ifndef __TCP_CLIENT_DEMO_H
 4 #define __TCP_CLIENT_DEMO_H
 5 #include "sys.h"
 6 #include "includes.h"
 7   
 8  
 9  
10 #define TCP_CLIENT_RX_BUFSIZE      1460    //接收缓冲区长度
11 #define REMOTE_PORT                      8087    //定义远端主机的IP地址
12 #define LWIP_SEND_DATA                0X80    //定义有数据发送
13 
14 
15 extern u8 tcp_client_recvbuf[TCP_CLIENT_RX_BUFSIZE];    //TCP客户端接收数据缓冲区
16 extern u8 tcp_client_flag;        //TCP客户端数据发送标志位
17 extern u8 recflag;
18 
19 INT8U tcp_client_init(void);  //tcp客户端初始化(创建tcp客户端线程)
20 #endif
  1 //tcp_client_demo.c
  2 
  3 #include "t"
  4 #include "lwip/opt.h"
  5 #include "lwip_comm.h"
  6 #include "lwip/lwip_sys.h"
  7 #include "lwip/api.h"
  8 #include "includes.h"
  9 #include "key.h"
 10 #include "malloc.h"
 11 #include "lcd.h"
 12 #include "recorder.h"
 13 
 14 struct netconn *tcp_clientconn;                                                              //TCP CLIENT网络连接结构体
 15 
 16 u8 tcp_client_recvbuf[TCP_CLIENT_RX_BUFSIZE];                                        //TCP客户端接收数据缓冲区
 17 
 18 u8 *tcp_Client_sendbuf;
 19 u8 recflag=0;
 20 
 21 
 22 
 23 //TCP客户端任务
 24 #define TCPCLIENT_PRIO        6
 25 //任务堆栈大小
 26 #define TCPCLIENT_STK_SIZE    300
 27 //任务堆栈
 28 OS_STK TCPCLIENT_TASK_STK[TCPCLIENT_STK_SIZE];
 29 
 30 void my_tcp_client_thread(void *arg)
 31 {
 32     OS_CPU_SR cpu_sr;
 33     
 34     u32 data_len = 0;                                                                //已接收数据长度
 35     struct pbuf *q;                                                                  //定义一个数据包来存储数据
 36     err_t err,recv_err;                                                              //标志位
 37     
 38     static ip_addr_t server_ipaddr,loca_ipaddr;                                      //服务器IP 本地IP
 39     
 40     static u16_t          server_port,loca_port;                                          //服务器端口 本地端口号
 41     u8 server_ip[4];
 42     
 43     u8 i;
 44     u8 re=0;
 45     tcp_Client_sendbuf=mymalloc(SRAMEX,SAI_RX_DMA_BUF_SIZE);
 46     
 47     for(i=0;i<SAI_RX_FIFO_SIZE;i++)
 48     {
 49         sairecfifobuf2[i]=mymalloc(SRAMEX,SAI_RX_DMA_BUF_SIZE);//SAI接收FIFO内存申请
 50         if(sairecfifobuf2[i]==NULL)break;            //申请失败
 51     }
 52     if(!tcp_Client_sendbuf||i!=SAI_RX_FIFO_SIZE) re=1;
 53     while(re);
 54     
 55     
 56     LWIP_UNUSED_ARG(arg);                                                            //告诉LWIP这个参数没用
 57     
 58     server_port = REMOTE_PORT;                                                       //服务器端口为 8087
 59     
 60     IP4_ADDR(&server_ipaddr, lwipdev.remoteip[0],lwipdev.remoteip[1], lwipdev.remoteip[2],lwipdev.remoteip[3]); //设置IPV4的地址即服务器地址为192.198.1.100
 61     
 62     server_ip[0] = lwipdev.remoteip[0];
 63     server_ip[1] = lwipdev.remoteip[1];
 64     server_ip[2] = lwipdev.remoteip[2];
 65     server_ip[3] = lwipdev.remoteip[3];
 66     
 67     while (1) 
 68     {
 69         tcp_clientconn = netconn_new(NETCONN_TCP);                                     //创建一个TCP链接
 70         
 71         err = netconn_connect(tcp_clientconn,&server_ipaddr,server_port);              //一直连接服务器
 72         
 73         if(err != ERR_OK)  
 74             netconn_delete(tcp_clientconn);                                              //返回值不等于ERR_OK,删除tcp_clientconn连接
 75         else if (err == ERR_OK)                                                        //已经连接上了 处理新连接的数据
 76         { 
 77             struct netbuf *recvbuf;                                                      //定义netbuf数据包 
 78             tcp_clientconn->recv_timeout = 10;                                           // 延迟10ms禁止线程阻塞
 79             netconn_getaddr(tcp_clientconn,&loca_ipaddr,&loca_port,1);                   //获取本地IP主机IP地址和端口号
 80             
 81             
 82             u8 *tbuf;                                              //使用LCD需要
 83             tbuf=mymalloc(SRAMIN,200);                               //申请内存
 84             POINT_COLOR = BLUE; 
 85             sprintf((char*)tbuf,"Server IP:%d.%d.%d.%d",server_ip[0],server_ip[1],server_ip[2],server_ip[3]);   //显示服务器IP
 86             LCD_ShowString(30,170,210,16,16,tbuf);
 87             sprintf((char*)tbuf,"Local Port:%d",loca_port);                              //本地端口号
 88             LCD_ShowString(30,190,210,16,16,tbuf);
 89             myfree(SRAMIN,tbuf);                                                         //一定要释放内存否则会卡死
 90             
 91             while(1)
 92             {
 93                     wav_buffill(tcp_Client_sendbuf);
 94                     while(netconn_write(tcp_clientconn ,tcp_client_recvbuf,1460,NETCONN_COPY));
 95 
 96                     OSTimeDlyHMSM(0,0,0,20);
 97 
 98 
 99                     
100                 if((recv_err = netconn_recv(tcp_clientconn,&recvbuf)) == ERR_OK)           //接收到数据
101                 {    
102                     OS_ENTER_CRITICAL();                                                     //关中断
103                     memset(tcp_client_recvbuf,0,TCP_CLIENT_RX_BUFSIZE);                      //数据接收缓冲区清零
104         
105                     for(q=recvbuf->p;q!=NULL;q=q->next)                                      //遍历完整个pbuf链表
106                     {
107                         if(q->len > (TCP_CLIENT_RX_BUFSIZE-data_len)) 
108                             memcpy(tcp_client_recvbuf+data_len,q->payload,(TCP_CLIENT_RX_BUFSIZE-data_len));//判断要拷贝到TCP_CLIENT_RX_BUFSIZE中的数据是否大于TCP_CLIENT_RX_BUFSIZE的剩余空间,如果大于的话就只拷贝TCP_CLIENT_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据
109                         else 
110                             memcpy(tcp_client_recvbuf+data_len,q->payload,q->len);
111                         
112                         data_len += q->len;                                                       //
113                         
114                         if(data_len > TCP_CLIENT_RX_BUFSIZE)  
115                break;                                                                        //超出TCP客户端接收数组,跳出    
116                     }
117                     rec_sai_fifo_write2(tcp_client_recvbuf);
118                     recflag++;
119                     
120                     OS_EXIT_CRITICAL();                                                      //开中断
121                 
122                     
123                     data_len=0;                                                              //复制完成后data_len要清零。                    
124                     netbuf_delete(recvbuf);
125                 }
126                 else if(recv_err == ERR_CLSD)                                              //关闭连接
127                 {
128                     netconn_close(tcp_clientconn);
129                     netconn_delete(tcp_clientconn);
130                     LCD_ShowString(30,170,210,16,16,"                                    ");
131                     LCD_ShowString(30,190,210,16,16,"Connect closed                      ");
132                     break;
133                 }
134             }
135         }
136     }
137      
138 }
139 
140 
141 //创建TCP客户端线程
142 //返回值:0 TCP客户端创建成功
143 //        其他 TCP客户端创建失败
144 INT8U tcp_client_init(void)
145 {
146     INT8U res;
147     OS_CPU_SR cpu_sr;
148     
149     OS_ENTER_CRITICAL();    //关中断
150     res = OSTaskCreate(my_tcp_client_thread,(void*)0,(OS_STK*)&TCPCLIENT_TASK_STK[TCPCLIENT_STK_SIZE-1],TCPCLIENT_PRIO); //创建TCP客户端线程
151     OS_EXIT_CRITICAL();        //开中断
152     
153     return res;
154 }
原文地址:https://www.cnblogs.com/Lxk0825/p/12718585.html