开发板用的是NodeMCU-32,库是esp-idf的4.3版本,从tcp server的例程改过来的。
#include <string.h>
#include <sys/param.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_netif.h"
#include "protocol_examples_common.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include <lwip/netdb.h>
#include "driver/gpio.h"
#define PORT CONFIG_EXAMPLE_PORT
#define KEEPALIVE_IDLE CONFIG_EXAMPLE_KEEPALIVE_IDLE
#define KEEPALIVE_INTERVAL CONFIG_EXAMPLE_KEEPALIVE_INTERVAL
#define KEEPALIVE_COUNT CONFIG_EXAMPLE_KEEPALIVE_COUNT
//tcp服务器开启监听的端口号
#define PORT_0 3333 //(PORT+0)
#define PORT_1 3334 //(PORT+1)
#define PORT_2 3335 //(PORT+2)
#define PORT_3 3336 //(PORT+3)
#define PORT_4 3337 //(PORT+4)
#define PORT_5 3338 //(PORT+5)
//自定义的tcp任务参数结构体
typedef struct TCP_SERVER_TASK_PARAM_t{
int addr_family; //地址类型,可赋值AF_INET,AF_INET6
int sock; //该任务处理的socket,只允许用socketBSD提供的api来对其读写
int port; //端口号
int task_ID; //处理该参数结构体的task的ID号,目前考虑和端口号port绑定
char TAG[32]; //日志tag
}tcp_server_task_param_t;
//tcp任务参数初始化
static void tcp_task_param_init(tcp_server_task_param_t* param, int set_port, char* set_tag)
{
//由于我自己水平不够,目前只提供ipv4的初始化,只能设置端口号和日志号
param->addr_family = AF_INET;
param->sock = 0;
param->port = set_port;
param->task_ID = set_port-PORT_0;
strcpy(param->TAG,set_tag);
}
tcp_server_task_param_t tcp_task_param[6];//分别对应到六个任务上去
#define TASK_ID_MIN 0
#define TASK_ID_MAX 3 //目前app_main里面只开了四个tcp_task 0~3
static const char *BROADCAST_TAG = "broadcast";
static void do_broadcast(const int cur_sock,int cur_task_ID)
{
//根据例程里的do_retransmit函数改过来的广播函数
//cur_task_ID从调用该函数的任务里传过来,该参数用于排除自己端口以进行广播
int len;
char rx_buffer[128];
do {
len = recv(cur_sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
if (len < 0) {
ESP_LOGE(BROADCAST_TAG, "Error occurred during receiving: errno %d", errno);
} else if (len == 0) {