1.创建等链接套接字fd=socket()
sock = socket(AF_INET,SOCK_DGRAM,0);
参数说明:
AF_INET --- IPV4的都是使用这个
SOCK_DGRAM ----指明协议是UDP TCP的是SOCK_STREAM
0 -----这个是服务 UDP和TCP都是0
2.绑定待链接套接字bind(fd,服务器ip和端口)
bind(sock,(struct sockaddr *)&Loacl_addr,sizeof(Loacl_addr));
参数说明:
sock ---- 第一步创建的套接字socket描述符
Loacl_addr ----- 设置本地的端口等信息
sizeof(Loacl_addr) ------ 结构体的长度
具体的设置:
struct sockaddr_in Loacl_addr; //设置本地端口
Loacl_addr.sin_addr.s_addr = htonl(INADDR_ANY);
Loacl_addr.sin_family = AF_INET;
Loacl_addr.sin_port = htons(54321);
3.等待信息recvfrom(fd,对端地址)
len =recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&source_addr, &socklen);
参数说明:
sock ---- 第一步创建的套接字socket描述符
rx_buffer ----接收的缓冲区
sizeof(rx_buffer) - 1 -----接收缓冲区的大小
0 -----指明用户控制接收的方式 通常是0
source ------ 目标地址的信息
socklen ----- source结构体的长度
二、具体代码
在wifi连接成功之后触发UDP的初始化,首先发送一个字符串,然后等待接收,把接收到的数据原路返回
#include <string.h>
#include <sys/param.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "tcpip_adapter.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include <lwip/netdb.h>
#define HOST_IP_ADDR "255.255.255.255"
#define PORT 12345
int sock = 0;
struct sockaddr_in dest_addr;
TaskHandle_t xUDPRecvTask = NULL;
void udp_recv_data(void *pvParameters){
uint8_t rx_buffer[1024] = {0};
printf("create udp recv\n");
int err = sendto(sock, "udp test", strlen("udp test"), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
if (err < 0) {
printf( "Error occurred during sending: errno %d", errno);
return;
}
printf("Message sent");
struct sockaddr_in source_addr; // Large enough for both IPv4 or IPv6
socklen_t socklen = sizeof(source_addr);
while (1)
{
int len = recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&source_addr, &socklen);
if(len > 0){
rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
printf("Received %d bytes from %s:\n", len, rx_buffer);
int err = sendto(sock, rx_buffer, len, 0, (struct sockaddr *)&source_addr, sizeof(source_addr));
if (err < 0) {
printf( "Error occurred during sending: errno %d", errno);
return;
}
printf("Message sent");
}
}
}
void udp_ini_client(void){
sock = socket(AF_INET,SOCK_DGRAM,0);
printf("sock:%d\n",sock);
if(sock < 0){
printf( "Unable to create socket: errno %d", errno);
return;
}
printf("Socket created, sending to %s:%d", HOST_IP_ADDR, PORT);
dest_addr.sin_addr.s_addr = inet_addr(HOST_IP_ADDR); //设置目标IP地址
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(PORT);//目标端口
struct sockaddr_in Loacl_addr;
Loacl_addr.sin_addr.s_addr = htonl(INADDR_ANY);
Loacl_addr.sin_family = AF_INET;
Loacl_addr.sin_port = htons(54321); //设置本地端口
uint8_t res = 0;
res = bind(sock,(struct sockaddr *)&Loacl_addr,sizeof(Loacl_addr));
if(res != 0){
printf("bind error\n");
}//创建接收任务函数
xTaskCreate(&udp_recv_data,"udp_recv_data",2048*2,NULL,10,&xUDPRecvTask);
}