yahboom
HomeLearn
Solution
Blog
Online Store
About Us
EN/中文
ESP32 Core Board📖
1. ESP32 Introduction
  • 1. ESP32S3 Overview
  • 2. Environment Setup Introduction
  • 3. Dev Board Introduction
2. ESP-IDF Development Tutorial
1. Before Development
  • 1. Environment Setup (Windows)
  • 2. Environment Setup (Linux)
  • 3. Build and Flash
2. Basic Peripherals
  • 1. LED Control
  • 2. Button Detection
  • 3. Peripheral Interrupts
  • 4. ESP_TIMER
  • 5. GPTIMER
  • 6. Watchdog Timer
  • 7. DMA
  • 8. ADC
  • 9. PWM Breathing LED
  • 10. RGB LED Effects
3. Serial Communication and Storage System
  • 1. Serial UART Communication Experiment
  • 2. I2C_OLED Display Experiment
  • 3. SPI Bus Communication Experiment
  • 4. PSRAM External Memory Experiment
  • 5. Flash Read and Write Experiment
  • 6. USB Emulated Mass Storage Experiment
4. FreeRTOS operating system
  • 1.FreeRTOS Core Concepts Theory
  • 2.Task Creation and Management
  • 3.Queue
  • 4.Binary Semaphore
  • 5.Mutex
  • 6.Event Groups
  • 7.Software Timer
  • 8.Task Scheduler
  • 9.Low Power Mode
  • 10.Deadlock
  • 11.Priority Inversion
5. Network Protocols and Wireless Communication
  • 1. WIFI Network Basics
  • 2. WIFI STA Mode
  • 3. WIFI AP Mode
  • 4. UDP Client Experiment
  • 5. UDP Server Experiment
  • 6. TCP Client Experiment
  • 7. TCP Server Experiment
  • 8. Socket Programming Basics
  • 9. HTTP Client Experiment
  • 10. HTTP Server Experiment
  • 11. MQTT IoT Communication Protocol
  • 12. WIFI OTA Upgrade
  • 13. Bluetooth Fundamentals
  • 14. Bluetooth Slave Mode
  • 15. Bluetooth Master Mode
6. Audio Applications
  • 1.I2S Microphone Recording and U-Disk Playback
  • 2.I2S Audio Playback Experiment
  • 3.Repeater Experiment
7. Xiaozhi AI Voice
  • 1. Burn Xiaozhi Firmware
  • 2. Network and Configuration
  • 3. AI Agent Settings
  • 4. Program Analysis
  • 5. Free Chat
3. Arduino Development Course
1. Before Development
  • 1. Environment Setup
  • 2. Build and Flash
2. Basic Peripherals
  • 1. LED Control
  • 2. Button Detection
  • 3. Peripheral Interrupts
  • 4. ESP_TIMER
  • 5. GPTIMER
  • 6. Watchdog Timer
  • 7. ADC
  • 8. PWM Breathing LED
  • 9. RGB LED Effects
3. Serial Communication and Storage System
  • 1. Serial UART Communication
  • 2. I2C OLED Display
  • 3. SPI Bus Communication
  • 4. Flash Read and Write
  • 5. USB Emulated Mass Storage
4. Network Protocols and Wireless Communication
  • 1. WIFI Network Basics
  • 2. WIFI STA Mode
  • 3. WIFI AP Mode
  • 4. UDP Server Experiment
  • 5. UDP Client Experiment
  • 6. TCP Client Experiment
  • 7. TCP Server Experiment
  • 8. HTTP Client Experiment
  • 9. HTTP Server Experiment
  • 10. MQTT IoT Communication Protocol
  • 11. WIFI OTA Upgrade
  • 12. Bluetooth Fundamentals
  • 13. Bluetooth Slave Mode
  • 14. Bluetooth Master Mode
5. Audio Applications
  • 1.I2S Microphone Recording and U-Disk Playback
  • 2.I2S Audio Playback Experiment
  • 3.Repeater Experiment
4. MicroPython Development Course
1. Before Development
  • 1. Environment Setup
  • 2. Build and Flash
  • 3. Thonny IDE
2. Basic Peripherals
  • 1. LED Control
  • 2. Button Detection
  • 3. Peripheral Interrupts
  • 4. TIMER_IT
  • 5. Watchdog Timer
  • 6. ADC
  • 7. PWM Breathing LED
  • 8. RGB LED Effects
3. Serial Communication and Storage System
  • 1. Serial UART Communication Experiment
  • 2. I2C_OLED Display Experiment
  • 3. SPI Bus Communication Experiment
  • 4. Flash Read and Write Experiment
  • 5. Print Storage
4. Network Protocols and Wireless Communication
  • 1. WIFI Network Basics
  • 2. WIFI STA Mode
  • 3. WIFI AP Mode
  • 4. UDP Client Experiment
  • 5. UDP Server Experiment
  • 6. TCP Client Experiment
  • 7. TCP Server Experiment
  • 8. HTTP Client Experiment
  • 9. HTTP Server Experiment
  • 10. MQTT
  • 11. Bluetooth Fundamentals
  • 12. Bluetooth Slave Mode
  • 13. Bluetooth Master Mode
5. Audio Applications
  • 1. I2S Audio Playback Experiment
  • 2. Repeater Experiment
Download
  • Code
  • Hardware_Info
  • 3D_Model_File
  • Software_Tools
  • VMware
  • VM_File
Download ZIP

Welcome to ESP32 Core Board repository

7. TCP Server Experiment

TCP Server Experiment


TCP Server Experiment1. TCP Overview2. Core Concepts2.1 TCP Three-Way Handshake2.2 TCP vs UDP API Comparison2.3 Three Return Values of recv()3. Project Architecture and Flow3.1 TCP Server4. Hardware Dependencies5. Source Code Analysis — TCP Client5.3 vTcpClientTask() — TCP Client Core5. Source Code Analysis — TCP Server5.1 Macro Configuration5.2 WiFi Initialization (Review)5.3 vTcpServerTask() — TCP Server Core6. Operation Flow6.1 Build and Flash Flow6.2 Testing Method6.3 Normal Log — TCP Server7. Common Problems


1. TCP Overview

TCP (Transmission Control Protocol) is a connection-oriented, reliable, byte-stream transport layer protocol. It establishes connections via three-way handshake, ensuring data arrives in order and intact.

FeatureTCPUDP
ConnectionThree-way handshakeConnectionless
ReliabilityGuaranteed delivery, guaranteed orderNot guaranteed
Flow/ Congestion ControlBuilt-in sliding window, slow startNone
Transmission ModeByte stream (no message boundaries)Datagram (has message boundaries)
Server APIbind → listen → accept → recv/sendbind → recvfrom/sendto
Client APIsocket → connect → recv/sendsocket → sendto/recvfrom

TCP is the foundation of IoT communications. Whether HTTP web requests, MQTT message publishing, OTA firmware upgrades, or database remote connections, all rely on TCP's reliable transmission at the bottom. In industrial automation, smart home, and remote monitoring scenarios, devices report sensor data and receive control instructions—all requiring "no data loss, no order disruption"—which is TCP's core value. UDP is fast but unreliable; TCP has the overhead of three-way handshake but gains an end-to-end acknowledgment and retransmission mechanism, irreplaceable in most IoT scenarios.

This project contains both TCP client and server routines: the client connects to the server and sends data periodically; the server listens on a port, accepts client connections, sends/receives data, and supports reconnecting after client disconnection.


2. Core Concepts

2.1 TCP Three-Way Handshake

  Client                               Server
    │                                    │
    │──── SYN (seq=x) ──────────────────→│  1. Client requests connection
    │                                    │
    │←─── SYN+ACK (seq=y, ack=x+1) ─────│  2. Server acknowledges + requests
    │                                    │
    │──── ACK (ack=y+1) ────────────────→│  3. Client acknowledges
    │                                    │
    │═══════ ESTABLISHED ═══════════════│

In code, the client calls connect() to trigger the handshake, and the server calls accept() to wait for handshake completion.

2.2 TCP vs UDP API Comparison

​x
// === TCP Server ===                        // === UDP Server ===
socket(AF_INET, SOCK_STREAM, 0)            socket(AF_INET, SOCK_DGRAM, 0)
bind(fd, addr, len)                        bind(fd, addr, len)
listen(fd, 5)                              // No listen
client_fd = accept(fd, ...)                // No accept, use recvfrom directly
recv(client_fd, buf, len, 0)              recvfrom(fd, buf, len, 0, &addr, &len)
send(client_fd, buf, len, 0)              sendto(fd, buf, len, 0, &addr, len)

// === TCP Client ===                        // === UDP Client ===
socket(AF_INET, SOCK_STREAM, 0)            socket(AF_INET, SOCK_DGRAM, 0)
connect(fd, &addr, len)                    // No connect
send(fd, buf, len, 0)                     sendto(fd, buf, len, 0, &addr, len)
recv(fd, buf, len, 0)                     recvfrom(fd, buf, len, 0, &addr, &len)

2.3 Three Return Values of recv()

Return ValueMeaningHandling
> 0Received n bytes of dataProcess normally
= 0Peer closed connection normally (sent FIN)close() and break
< 0No data available (non-blocking) or errorIgnore with MSG_DONTWAIT; check errno for others

recv() == 0 is a TCP-specific "peer closed" signal; UDP has no such concept.


3. Project Architecture and Flow

3.1 TCP Server

xxxxxxxxxx
app_main()
  ├─ wifi_init()                         ← WiFi STA init (wait for IP)
  │
  └─ xTaskCreate(vTcpServerTask, ...)   ← Create TCP server task
      └─ vTcpServerTask():
          ├─ socket(AF_INET, SOCK_STREAM, 0)  → Create TCP socket
          ├─ bind(INADDR_ANY, 8080)           → Bind port
          ├─ listen(fd, 5)                    → Start listening (max 5 queued)
          └─ while(1):
              ├─ accept() [blocking] → Wait for client connection
              └─ inner while(1):
                  ├─ recv(MSG_DONTWAIT) → Non-blocking receive
                  ├─ data received → send() reply
                  ├─ recv==0 → client disconnected, break
                  └─ close(client_fd) → Return to outer accept

4. Hardware Dependencies

  • Hardware Connection: No external wiring, WiFi wireless communication

  • Required Components: lwip/sockets, esp_wifi, esp_netif, esp_event, nvs_flash, FreeRTOS


5. Source Code Analysis — TCP Client

Full source: Source Code → ESP-IDF → 5.Network_Protocol → 4.TCP → TCP_Server

5.3 vTcpClientTask() — TCP Client Core

The biggest difference from UDP client: TCP is "make a call before speaking"—connect() three-way handshake succeeds before send()/recv(). UDP is "send a letter directly"—sendto() doesn't need a connection first. Also TCP uses SOCK_STREAM (streaming), UDP uses SOCK_DGRAM (datagram).

In the send-receive loop, a key judgment—recv() returning 0 means the server normally closed the connection (sent FIN package), then break out to close socket and delete task. UDP has no this problem because UDP is connectionless, recvfrom() never returns 0.

 


5. Source Code Analysis — TCP Server

Full source: Source Code → ESP-IDF → 5.Network_Protocol → 4.TCP → TCP_Server

5.1 Macro Configuration

These macros define WiFi connection info and TCP server address. Modify SSID, password, and target IP according to your network environment.

xxxxxxxxxx
#define WIFI_SSID        "Your_WiFi_SSID"       // WiFi SSID
#define WIFI_PASS        "Your_WiFi_Password"   // WiFi password
#define TCP_SERVER_IP    "192.168.11.183"       // Server IP
#define TCP_SERVER_PORT  8080                   // Server port
#define WIFI_TIMEOUT_MS  15000

5.2 WiFi Initialization (Review)

The WiFi STA connection code in this experiment (wifi_init_sta(), event callback, NVS init, etc.) is identical to 5.2 WIFI-STA Mode. app_main() does NVS init → WiFi connection to get IP → xTaskCreate() for TCP task.

For details, review: 5. Network Protocols and Wireless Communication -> 2. WIFI-STA Mode -> WIFI-STA Mode

5.3 vTcpServerTask() — TCP Server Core

The TCP server has three extra steps compared to the client: bind() to occupy the port, listen() to start queuing, accept() to "answer the phone". It uses a dual-loop structure—the outer loop continuously accept() waits for the next client, the inner loop handles send/receive for the current client. When the client leaves, close(client_fd) returns to the outer loop to continue waiting.

listen(fd, 5)'s 5 doesn't mean "max 5 clients", but max 5 clients queued waiting for accept. Already-accepted clients don't count. Non-blocking MSG_DONTWAIT mode is also used for receiving data—if no data, skip; if data received, automatically reply.

xxxxxxxxxx
void vTcpServerTask(void *pv)
{
    int listen_fd;                // Listen socket
    int client_fd;                // Client socket
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_len;
    char recv_buf[128];
    char reply_msg[] = "Hello from ESP32 TCP Server!";
    // Create TCP socket
    listen_fd = socket(AF_INET, SOCK_STREAM, 0);

    server_addr.sin_family = AF_INET;

    // Listen on all IP
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(TCP_SERVER_PORT);
    // Bind port
    bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    // Start listening
    listen(listen_fd, 5);         // Max 5 clients queued
    ESP_LOGI(TAG, "TCP Server listening on port %d", TCP_SERVER_PORT);

    while (1) {
        // Wait for client connection (blocking)
        client_len = sizeof(client_addr);
        client_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &client_len);

        if (client_fd < 0) {
            ESP_LOGE(TAG, "Accept failed");
            continue;
        }
        ESP_LOGI(TAG, "Client connected!");
        // Inner loop: communicate with current client
        while (1) {
            memset(recv_buf, 0, sizeof(recv_buf));
            int recv_len = recv(client_fd, recv_buf, sizeof(recv_buf)-1, MSG_DONTWAIT);

            if (recv_len > 0) {
                ESP_LOGI(TAG, "Receive from client: %s", recv_buf);
                send(client_fd, reply_msg, strlen(reply_msg), 0);
                ESP_LOGI(TAG, "Reply to client: %s", reply_msg);
            } else if (recv_len == 0) {
                // Client disconnected
                ESP_LOGI(TAG, "Client disconnected");
                break;
            }
            vTaskDelay(10);
        }
        close(client_fd);
    }
    close(listen_fd);
    vTaskDelete(NULL);
}

6. Operation Flow

6.1 Build and Flash Flow

ESP-IDF Flash Flow: See ESP-IDF → 1. Before Development → 3. Build and Flash.

6.2 Testing Method

  1. Run a network debugging assistant on PC, select TCP Server mode, listen on port 8080.

Network Debug Assistant Icon

  1. Flash TCP_Server to ESP32. PC as TCP Client connects to ESP32's IP:8080, sends any data, ESP32 automatically replies.

Server Serial Output

6.3 Normal Log — TCP Server

xxxxxxxxxx
I (2856) TCP-SERVER: Got IP: 192.168.11.100
I (2858) TCP-SERVER: WiFi connected successfully!
I (2860) TCP-SERVER: TCP Server listening on port 8080
I (5000) TCP-SERVER: Client connected!
I (5002) TCP-SERVER: Receive from client: ESP32 TCP Client Data
I (5004) TCP-SERVER: Reply to client: Hello from ESP32 TCP Server!

Server Log Output 2


7. Common Problems

SymptomCauseSolution
connect() returns -1, connection failedServer not started or wrong IPConfirm PC TCP Server is listening, IP and port are correct
Server accept() blocks and doesn't returnNo client connectedNormal behavior, it's a blocking call
Client recv() returns 0Server actively closed connectionNormal disconnect, break then close()
Consecutive send() failuresPeer closed / network interruptedTCP connection broken, need to connect() again
bind() failedPort in useUse a different port / wait 2 minutes (TIME_WAIT timeout)
recv() data "sticks" togetherTCP is byte stream, no message boundariesDefine frame header+length or delimiter protocol at application layer
Server can only connect one clientSingle-threaded sequential processingChange to xTaskCreate for each accept() for independent tasks
Meaning of listen() second parameter 5Not max connections, it's the pending connection queue lengthAlready-accepted connections don't count
TCP Client Experiment
Socket Programming Basics

COMPANY

  • About us
  • Team Style
  • Blog

LEARNING & EXPLORATION

  • Tutorials
  • Edge AI hardware
  • Educational robots
  • Embedded intelligent hardware

WHERE TO BUY

  • Yahboom Online Store
  • Amazon
  • Alibaba
  • AliExpress
  • Mercado

TECHNOLOGY SUPPORT

  • Email: support@yahboom.com

BE A DISTRIBUTOR

  • Email: sales@yahboom.com
QR Code
QR Code

Copyright © 2017-2026 Yahboom. All Rights Reserved.

EN/中文