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