This article comes from the secondary column WiFi and Lwip protocol stack on ESP32 under the original column ESP32 teaching column (based on ESP-IDF), which explains how to use ESP-IDF to build ESP32 programs, publish articles and continue to add new content to published articles! Every article has been finely polished!
↓↓↓ enter the column home page through the link below ↓↓↓
-
Column home page: Click to enter → ESP32 teaching column (based on ESP-IDF)
-
Level 2 column: Click to enter → WiFi on ESP32
1, Establish connection - ESP32 as TCP Client
1. Basic idea of TCP client
2. TCP Client code example
The following code is a TCP function_ Task_ The client implements a FreeRTOS Task, in which the following contents are completed:
- Wait for WiFi connection to succeed (Event Group based on FreeRTOS API)
- Create a Socket object and initially set it to TCP (note line 7 of the code), and check whether the Socket is created successfully.
- Configure the connection parameter structure (struct sockaddr_in type desk_addr)
- Connect the server circularly until the connection is successful
See notes for details
void tcp_task_client(void *arg){ xEventGroupWaitBits(wifiEvent, wifiConnectedBit, pdFALSE, pdFALSE, portMAX_DELAY); int _socket; createSocket: // label _socket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); // AF_INET indicates IPv4, AF_INET6 stands for IPv6 // SOCK_STREAM means TCP; // SOCK_DGRAM stands for UDP; // SOCK_RAW means RAW // Protocol, which specifies which type of protocol data the socket sends and receives. // The most common is IPPROTO_TCP, IPPROTO_UDP, IPPROTO_UDPLITE,IPPROTO_ICMP. // If domain and type have determined a unique protocol, "0 (IPPROTO_IP)" can be used to select a default protocol. if(_socket < 0){ printf("Socket Creation failed, Error code:%d\n", errno); vTaskDelete(NULL); }else{ printf("Socket Created successfully"); } struct sockaddr_in desk_addr = { // The following IP 192.168.31.138 and port number 8080 are set by yourself. Please modify them as needed .sin_addr.s_addr = inet_addr("192.168.31.138"), .sin_family = AF_INET, .sin_port = htons(8080), // Small end mode to large end mode }; int err; while (1) { err = connect(_socket, (struct sockaddr*)&desk_addr, sizeof(desk_addr)); if (err == 0){ ESP_LOGI("CLIENT", "Connection succeeded"); break; }else{ ESP_LOGI("CLIENT", "Connection failed with error code:%d", errno); close(_socket); vTaskDelay(pdMS_TO_TICKS(200)); goto createSocket; // goto tag } } vTaskDelete(NULL); }
2, Establish connection - ESP32 as TCP Server
1. Code example
The following code is a TCP function_ Task_ Server implements a FreeRTOS Task, in which the following contents are completed:
- Wait for WiFi connection to succeed (Event Group based on FreeRTOS API)
- Create a Socket object and initially set it to TCP (note line 7 of the code), and check whether the Socket is created successfully.
- Configure the connection parameter structure (struct sockaddr_in type desk_addr)
- binding
- Start listening
- Execute the accept function to remove the Socket from the client Sockets that have established a TCP connection (this function will block, so please make it appear in the appropriate position as needed)
See notes for details
void tcp_task_server(void *arg){ xEventGroupWaitBits(wifiEvent, wifiConnectedBit, pdFALSE, pdFALSE, portMAX_DELAY); int _socket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if(_socket < 0){ printf("Socket Creation failed, Error code:%d\n", errno); vTaskDelete(NULL); }else{ printf("Socket Created successfully"); } struct sockaddr_in desk_addr = { .sin_addr.s_addr = INADDR_ANY, .sin_family = AF_INET, .sin_port = htons(2501), // Small end mode to large end mode }; int err; while(1){ err = bind(_socket, (struct sockaddr*)&desk_addr, sizeof(desk_addr)); if(err == 0){ ESP_LOGI("SERVICE", "Binding succeeded"); break; }else{ ESP_LOGI("SERVICE", "Binding failed, error code : %d", errno); } vTaskDelay(pdMS_TO_TICKS(1000)); } err = listen(_socket, 5); if (err != 0){ ESP_LOGI("SERVICE", "Listening failed, error code: %d", errno); vTaskDelete(NULL); }else{ ESP_LOGI("SERVICE", "Listening succeeded"); } while (1){ struct sockaddr_in6 source_addr; uint addr_len; ESP_LOGI("SERVICE", "get ready accept"); int remote_sock = accept(_socket, (struct sockaddr *) &source_addr, &addr_len); //xTaskNotifyGive(tcp_client_handle); if(remote_sock < 0){ ESP_LOGI("SERVICE", "accept Failed, error code: %d", errno); }else{ ESP_LOGI("SERVICE", "Connection succeeded"); break; } vTaskDelay(pdMS_TO_TICKS(1000)); } vTaskDelete(NULL); }
3, Send and receive data
4, LwIP BSD API functions related to TCP/UDP
socket() bind() listen() connect() accept() send(), recv(), sendto(), recvfrom() close() gethostbyname() select() pool() getsockopt(), setsockopt()
Function name | socket() |
---|---|
Function prototype | int socket(int domain, int type, int protocol) |
meaning | The function socket() creates an endpoint for communication and returns a file descriptor for the socket. |
Return value | int, returns - 1 if an error occurs |
parameter | domain type: int; Represents the protocol family you want to create. For example: AF_INET means IPv4, AF_INET6 indicates IPv6, AF_UNIX represents a local socket type: int; E.g. SOCK_STREAM means TCP, SOCK_DGRAM stands for UDP, SOCK_SEQPACKET means reliable sequential package service, SOCK_RAW represents the original protocol on the network layer The protocol type is: int; Indicates the actual transport protocol to use. The most common is IPPROTO_TCP, IPPROTO_SCTP, IPPROTO_UDP, IPPROTO_DCCP, etc. If 0 (IPPRORO_IP) is filled in, the protocol will be automatically selected according to the first two parameters |