zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    django的第一次使用
    python操作文件要点
    MySQL作业笔记及总结
    ASP.NET MVC——学习WebAPI
    编写PHP框架,深入了解MVC运行流程
    MySql(分表、增量备份、还原)
    ASP.NET MVC——MVC过滤器
    ASP.NET MVC——MVC-路由
    ASP.NET MVC——MVC4优化
    JS判断指定按键(组合键)是否被按下
  • 原文地址:https://www.cnblogs.com/Lxk0825/p/12718585.html
Copyright © 2011-2022 走看看