1. 程式人生 > 實用技巧 >ESP8266學習實戰之UdpClient與UdpSever(FreeRTOS)

ESP8266學習實戰之UdpClient與UdpSever(FreeRTOS)

Udpclient 任務流程

①判斷是否獲取ip地址

新建狀態變數

STATION_STATUS stastatus;

呼叫wifi介面,並判斷是否獲取IP地址

  ·do
        {
        stastatus = wifi_station_get_connect_status();
        vTaskDelay(100);
        }
    while (stastatus != STATION_GOT_IP);

②建立Socket

    int fd = -1;
        fd = socket(PF_INET,SOCK_DGRAM,0
); if(fd = -1) { printf("get socket fail!"); vTaskDelete(NULL); }

③設定接收超時時間

int setsockopt(int sock,int level,int optname,void *optval,socklen to optlen );

sock:將要被設定或者獲取選項的套接字

level:選項所在的協議層

optname:需要訪問的選項名

optval:對於getsockopt()指向返回值的緩衝,對於setsockopt()指向包含新選項的緩衝。

optlen:對於getsockop(),作為入口引數時,選項值得最大長度;作為出口引數時,選項值得實際長度。對於setsockopt(),現選項的長度。

  int NetTimeOut = 1000;
  setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &NetTimeOut, sizeof(int))

④賦值sever資訊

定義一個struct_sockaddr_in型別的變數並清空

struct sockaddr_in myaddr;

memset(&myaddr,0,sizeof(myaddr));

填充地址資訊

myaddr.sin_family = PF_INET;

myaddr.sin_port = htons(8888);

myaddr.sin_addr.s_addr = inet_addr("192.168.x.xxx");

將該變數強制轉換為struct sockaddr 型別在函式中使用

bind(listenfd,(struct sockaddr*)(&myaddr),sizeof(myaddr));

#define SEVERADDR "192.168.0.207"
#define SEVERPORT 8000

    struct sockaddr_in SeverAddr;
    memset(&SeverAddr,0,sizeof(SeverAddr));

    SeverAddr.sin_family = AF_INET;
    SeverAddr.sin_addr.s_addr = inet_addr(SEVERADDR);
    SeverAddr.sin_port = htons(SEVERPORT);
    SeverAddr.sin_len = sizeof(SeverAddr);    

⑤傳送資料到sever端

ssize t send(int socket,const void *buffer,size t length,int flages);

ssize t sendto( int s,const void *data ,size t size ,int falges,const struct sockaddr *to,socklen t tolen);

標頭檔案:#include<sys/socket.h>

buffer:傳送緩衝區首地址

length:傳送位元組數

flages:傳送方式(通常為0)

    //傳送資料
    sendto(fd, "I am Udp", sizeof("I am Udp"), 0, (struct sockaddr *)&SeverAddr, (socklen_t)SeverAddr.sin_len);

⑥從sever端接收資料

     int ret;
     char udpmsg[48];


do { ret = recvfrom(fd, udpmsg, 48, 0, (struct sockaddr *)&SeverAddr, (socklen_t*)(&SeverAddr.sin_len)); vTaskDelay(100); if(ret > 0) { printf("UdpSever:%s\n",udpmsg); } else printf("UdpSever data is no\n"); } while (ret == -1);

udpsever任務流程

直接複製SDK中的udpclient資料夾的所有檔案到新建資料夾udpsever中

在udpsever中新建udpsever.c和udpsever.h

將udpcline.c和udpcline.h中的程式碼分別複製到udpsever.c和udpsever.h中並修改標頭檔案以及函式名

修改sever地址

sever地址後新增

    if(bind(fd,(struct sockaddr*)&SeverAddr,SeverAddr.sin_len) != 0)
        {
            printf("bind socket fail!\n");
            vTaskDelete(NULL);
            return;
        }
    

修改發射接收端

struct sockaddr from;
socklen_t fromlen = sizeof(struct sockaddr);


for(;;) { do { ret = recvfrom(fd, udpmsg, 48, 0, &from, &fromlen); vTaskDelay(100); if(ret > 0) { printf("UdpClient:%s\n",udpmsg); } else printf("UdpClient data is Null\n"); } while (ret == -1); //傳送返回資料 sendto(fd, "I am UdpSever", sizeof("I am UdpSever"), 0, &from, fromlen); } vTaskDelete( NULL );

UDPClient原始碼:

//udpclient.c
#include "esp_common.h"
    
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
    
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "udpclient.h"

#define SEVERADDR "192.168.0.207"
#define SEVERPORT 8000

/******************************************************************************
 * FunctionName : ATaskUdpclient
 * Description  : ATaskUdpclient 任務
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ATaskUdpclient(void *pvParameters)
{
    int iVariableExample = 0;
    int fd = -1;
    int NetTimeOut = 5000;
    int ret;
    char udpmsg[48];

    STATION_STATUS stastatus;
    
    struct sockaddr_in SeverAddr;
    do
        {
        stastatus = wifi_station_get_connect_status();
        vTaskDelay(100);
        }while (stastatus != STATION_GOT_IP);
    
    fd = socket(PF_INET,SOCK_DGRAM,0);
    
    if(fd == -1)
        {
            printf("get socket fail!");
            vTaskDelete(NULL);
        }
    
    setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &NetTimeOut, sizeof(int));
    memset(&SeverAddr,0,sizeof(SeverAddr));

    SeverAddr.sin_family = AF_INET;
    SeverAddr.sin_addr.s_addr = inet_addr(SEVERADDR);
    SeverAddr.sin_port = htons(SEVERPORT);
    SeverAddr.sin_len = sizeof(SeverAddr);
    for(;;)
        {
            //傳送資料
            sendto(fd, "I am Udp", sizeof("I am Udp"), 0, (struct sockaddr *)&SeverAddr, (socklen_t)SeverAddr.sin_len);
            do
                {
                    ret = recvfrom(fd, udpmsg, 48, 0, (struct sockaddr *)&SeverAddr, (socklen_t*)(&SeverAddr.sin_len));
                    vTaskDelay(100);
                    if(ret > 0)
                        {
                            printf("UdpSever:%s\n",udpmsg);
                        }
                    else
                        printf("UdpSever data is no\n");
                }
            while (ret == -1);
        
            
        }
    vTaskDelete( NULL );
}

/******************************************************************************
 * FunctionName : Udpclient_init
 * Description  : Udpclient_init 初始化
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void Udpclient_init(void)
{
    xTaskCreate(ATaskUdpclient, "Udpclient", 256, NULL, 4 , NULL);
}

//udpclient.h
#ifndef __UART_H__
#define __UART_H__

#ifdef __cplusplus
extern "C" {
#endif

void ATaskUdpclient(void *pvParameters);
void Udpclient_init(void);

#ifdef __cplusplus
}
#endif

#endif

UDPSever原始碼:

//udpsever.c
#include "esp_common.h"
    
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
    
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "udpsever.h"

#define SEVERADDR "192.168.0.207"
#define SEVERPORT 8000

/******************************************************************************
 * FunctionName : ATaskUdpsever
 * Description  : ATaskUdpsever 任務
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ATaskUdpsever(void *pvParameters)
{
    int iVariableExample = 0;
    int fd = -1;
    int NetTimeOut = 5000;
    int ret;
    char udpmsg[48];

    STATION_STATUS stastatus;
    
    struct sockaddr_in SeverAddr;
    struct sockaddr from;
    socklen_t fromlen = sizeof(struct sockaddr);
    
    do
        {
        stastatus = wifi_station_get_connect_status();
        vTaskDelay(100);
        }while (stastatus != STATION_GOT_IP);
    
    fd = socket(PF_INET,SOCK_DGRAM,0);
    
    if(fd == -1)
        {
            printf("get socket fail!");
            vTaskDelete(NULL);
            return;
        }
    
    setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &NetTimeOut, sizeof(int));
    memset(&SeverAddr,0,sizeof(SeverAddr));

    SeverAddr.sin_family = AF_INET;
    SeverAddr.sin_addr.s_addr = INADDR_ANY;
    SeverAddr.sin_port = htons(SEVERPORT);
    SeverAddr.sin_len = sizeof(SeverAddr);

    if(bind(fd,(struct sockaddr*)&SeverAddr,SeverAddr.sin_len) != 0)
        {
            printf("bind socket fail!\n");
            vTaskDelete(NULL);
            return;
        }
    
    for(;;)
        {
            do
                {
                    ret = recvfrom(fd, udpmsg, 48, 0, &from, &fromlen);
                    vTaskDelay(100);
                    if(ret > 0)
                        {
                            printf("UdpClient:%s\n",udpmsg);
                        }
                    else
                        printf("UdpClient data is Null\n");
                }
            while (ret == -1);
        
            

            //傳送資料
            sendto(fd, "I am UdpSever", sizeof("I am UdpSever"), 0, &from, fromlen);

        }
    vTaskDelete( NULL );
}

/******************************************************************************
 * FunctionName : Udpsever_init
 * Description  : Udpsever_init 初始化
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void Udpsever_init(void)
{
    xTaskCreate(ATaskUdpsever, "Udpsever", 256, NULL, 4 , NULL);
}

//udpsever.h
#ifndef __UDPSEVER_H__
#define __UDPSEVER_H__

#ifdef __cplusplus
extern "C" {
#endif

void ATaskUdpsever(void *pvParameters);
void Udpsever_init(void);

#ifdef __cplusplus
}
#endif

#endif