ESP32做TCP服务端(server)与多个客户端通信
本文作为学习记录描述基于esp32已经连接WiFi上,通过socket实现esp32作为tcp服务端跟多个客户端(pc/esp32)进行数据传输。
配置环境
- ESP32(两块/多个pc端)目的是:需要一个做服务端和两个以上自身ip地址不一样的客户端
- vscode
- ESP-IDF
- TCP工具
官方示例
所有示例都在esp-idf的example里
本文只阐述TCP作为服务端的情况,如果想了解TCP作为客户端可查看上一篇文章
TCP作为服务端的socket基本工作流程
需要知道esp32作为tcp客户端的基本流程可以参考上一篇博客:
ESP32做TCP客户端(client)与PC通信(socket)
- socket初始化 socket()
- 绑定端口 blind()
- 监听客户端连接 listen()
- 创建连接通道 accept()
- 接收数据 recv()
- 发送数据 send()
- 断开连接 close()
ps:接收跟发送数据处于一个循环,反复调用进行数据传输
以下是根据示例移植到自己的工程下,所以略有改动(官方示例只能客户端跟服务端1v1通信,以下实现的功能是多个客户端也能跟服务端进行通信)
#include "usertcp_server.h"
#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 "sdkconfig.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 "addr_from_stdin.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include <lwip/netdb.h>
#define PORT 3333//CONFIG_EXAMPLE_PORT//端口号
#define KEEPALIVE_IDLE 5//CONFIG_EXAMPLE_KEEPALIVE_IDLE //tcp设置连接上如果没有数据发送的话,多久后发送keepalive探测分组(s)
#define KEEPALIVE_INTERVAL 5//CONFIG_EXAMPLE_KEEPALIVE_INTERVAL//tcp前后两次探测之间的时间间隔(s)
#define KEEPALIVE_COUNT 5//CONFIG_EXAMPLE_KEEPALIVE_COUNT //tcp关闭一个非活跃连接之前的最大重试次数(s)
static const char *TAG = "server";
static void do_retransmit(const int sock)
{
int len;
char rx_buffer[128];
do {
len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
if (len < 0) {
ESP_LOGE(TAG, "Error occurred during receiving: errno %d", errno);
} else if (len == 0) {
ESP_LOGW(TAG, "Connection closed");
} else {
rx_buffer[len] = 0; // Null-terminate whatever is received and treat it like a string将接收到的任何内容终止为空,并将其视为字符串
ESP_LOGI(TAG, "Received %d bytes: %s", len, rx_buffer);
// send() can return less bytes than supplied length. Send()返回的字节数可能少于提供的长度
// Walk-around for robust implementation.
int to_write = len;
while (to_write > 0) {