Chapter 16 TCP Connection of ESP32
Pay attention to the public account of Jiayouchuang Technology
- Source address: https://github.com/HX-IoT/ESP32-Developer-Guide
- ESP32 development guide QQ group: 824870185, there is a pdf version, and the layout is neat.
Learning goals and objectives
- Master the principle and working process of TCP
- Master the programming of the TCP of Espressif ESP32
- Mainly master the detailed process of TCP as Client
TCP science (from Baidu Encyclopedia)
TCP (Transmission Control Protocol ) is a connection-oriented, reliable , byte stream-based transport layer communication protocol, defined by IETF's RFC 793. In the simplified OSI model of computer network, it completes the functions specified by the fourth layer transport layer, the User Datagram Protocol (UDP) is the same layer, another important transport protocol. In the Internet protocol suite, the TCP layer is an intermediate layer above the IP layer and below the application layer. Reliable, pipe-like connections are often required between application layers of different hosts, but the IP layer does not provide such a streaming mechanism, but provides unreliable packet exchange.
The application layer sends a data stream represented by 8-bit bytes for Internet transmission to the TCP layer, and then TCP partitions the data stream into segments of appropriate length (usually controlled by the data link layer of the network to which the computer is connected). Maximum Transmission Unit (MTU) limit). Then TCP passes the result packet to the IP layer, which transmits the packet through the network to the TCP layer of the receiving entity. In order to ensure that no packet loss occurs, TCP gives each packet a sequence number, and the sequence number also ensures the orderly reception of packets transmitted to the receiving entity. The receiver entity then sends back a corresponding acknowledgment (ACK) for the successfully received packet; if the sender entity does not receive an acknowledgment within a reasonable round-trip delay ( RTT ), then the corresponding packet is assumed to have been Losses will be retransmitted. TCP uses a checksum function to check data for errors; checksums are calculated both when sending and receiving.
connection establishment
TCP is the transport layer protocol in the Internet and uses a three-way handshake protocol to establish connections. When the active party sends a SYN connection request, wait for the other party to answer SYN+ACK, and finally perform ACK confirmation on the other party's SYN. This method of establishing a connection prevents false connections, and the flow control protocol used by TCP is a variable-size sliding window protocol.
The process of the TCP three-way handshake is as follows:
- The client sends a SYN (SEQ=x) message to the server and enters the SYN_SEND state.
- The server receives the SYN message, responds with a SYN (SEQ=y) ACK (ACK=x+1) message, and enters the SYN_RECV state.
- The client receives the SYN message from the server, responds with an ACK (ACK=y+1) message, and enters the Established state.
-
- connection terminated
-
Terminating a connection requires a four-way handshake, which is caused by TCP's half-close. The specific process is shown in the figure below. [1]
- An application process first calls close, which is called an "active close". The TCP on this end then sends a FIN segment, indicating that the data is sent.
- The peer that receives this FIN performs a "passive close", and the FIN is acknowledged by TCP.
- After a period of time, the application process that receives this end-of-file will call close to close its socket. This causes its TCP to also send a FIN.
- The original sender TCP that received the final FIN (that is, the end that performed the active shutdown) confirms the FIN
TCP features and processes
The above principles are very important, but after all, we are only doing applications on top of the API. Just need to understand the features and processes . Knowing the characteristics, you can consider the feasibility when making a plan, and the process is the implementation after it is feasible.
TCP features:
- Connection-oriented: A connection must be made before sending data.
- Reliable connection: The data transmitted by the TCP connection is error-free, not lost, not duplicated, and arrives in sequence.
- Point-to-point: The data transmitted by the TCP connection is error-free, not lost, not repeated, and arrives in sequence
- Maximum length is limited: only 1500 bytes. ( http and websocket come into play )
TCP process: ( source of this paragraph )
The general steps of the client side of TCP programming are:
- Create a socket, use the function socket();
- To set socket properties, use the function setsockopt(); (optional)
- Bind IP address, port and other information to the socket, use the function bind();* optional
- Set properties such as the IP address and port of the other party to be connected;
- To connect to the server, use the function connect();
- To send and receive data, use the functions send() and recv(), or read() and write();
- close the network connection;
The general steps on the server side of TCP programming are:
- Create a socket, use the function socket();
- To set the socket property, use the function setsockopt(); (optional)
- Bind IP address, port and other information to the socket, use the function bind();
- To enable monitoring, use the function listen();
- To receive the connection from the client, use the function accept();
- To send and receive data, use the functions send() and recv(), or read() and write();
- Close the network connection; closesocket();
- close monitoring;
TCP and UDP (in the next chapter) fight each other
software design
The main logic of ESP32 's TCP Client (similar to Server)
Detailed process logic of new task and receiving task of TCP Client
Introduction to the TCP interface of ESP32
ESP32 uses LwIP. LwIP is a small open source TCP/IP protocol stack especially suitable for embedded devices, which occupies very little memory resources. ESP-IDF is a transplant of the LwIP protocol stack. Learn to understand LwIP, and recommend this book to everyone, "Things on Embedded Networks: In-depth Analysis and Practical Drills of LwIP Protocol".
Our routine directly uses the standard socket interface (internally encapsulated by LwIP), and does not use LwIP. The interface explanation about LwIP is explained in Websocket, and the usage is the same. After knowing the process, the API call can be used. Handle exceptions well. Process + interface, invincible. For the tutorial of LwIP, please refer to the documentation of Avnet and Wildfire.
The following macro definitions can be seen in the src/include/lwip/socket.h file. The socket of lwip also provides standard socket interface functions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #if LWIP_COMPAT_SOCKETS #define accept(a,b,c) lwip_accept(a,b,c) #define bind(a,b,c) lwip_bind(a,b,c) #define shutdown(a,b) lwip_shutdown(a,b) #define closesocket(s) lwip_close(s) #define connect(a,b,c) lwip_connect(a,b,c) #define getsockname(a,b,c) lwip_getsockname(a,b,c) #define getpeername(a,b,c) lwip_getpeername(a,b,c) #define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e) #define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e) #define listen(a,b) lwip_listen(a,b) #define recv(a,b,c,d) lwip_recv(a,b,c,d) #define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f) #define send(a,b,c,d) lwip_send(a,b,c,d) #define sendto(a,b,c,d,e,f) lwip_sendto(a,b,c,d,e,f) #define socket(a,b,c) lwip_socket(a,b,c) #define select(a,b,c,d,e) lwip_select(a,b,c,d,e) #define ioctlsocket(a,b,c) lwip_ioctl(a,b,c)
#if LWIP_POSIX_SOCKETS_IO_NAMES #define read(a,b,c) lwip_read(a,b,c) #define write(a,b,c) lwip_write(a,b,c) #define close(s) lwip_close(s) |
- New socket function: socket();
- Connection function: connect();
- Close the socket function: close();
- Get socket error code: getsocketopt();
- Receive data function: recv();
- Send data function: send();
- Binding function: bing();
- Listener function: listen();
- Get the connection function: accept();
For more detailed interfaces, please refer to the official guide .
Summary of TCP for ESP32
After initializing the wifi configuration, the program will return the status in the callback function according to the real-time status of the WIFI, so you only need to perform related operations in the callback, the STA start event triggers the TCP connection, and the data can be exchanged after the connection. Among them, it is extremely important to deal with abnormal conditions of the connection. TCP is reliable and cannot be used as a commodity.
Writing a new TCP task
Only talk about Client, server look at the source code .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | esp_err_t create_tcp_client() {undefined ESP_LOGI(TAG, "will connect gateway ssid : %s port:%d", TCP_SERVER_ADRESS, TCP_PORT); // create a new socket connect_socket = socket (AF_INET, SOCK_STREAM, 0); if (connect_socket < 0) {undefined //print error message show_socket_error_reason("create client", connect_socket); //After the new creation fails, close the newly created socket and wait for the next new creation close(connect_socket); return ESP_FAIL; } //Configure connection server information: port + ip server_addr.sin_family = AF_INET; server_addr.sin_port = htons(TCP_PORT); server_addr.sin_addr.s_addr = inet_addr(TCP_SERVER_ADRESS); ESP_LOGI(TAG, "connectting server..."); //connect to the server if (connect(connect_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {undefined //print error message show_socket_error_reason("client connect", connect_socket); ESP_LOGE(TAG, "connect failed!"); //After the connection fails, close the previously created socket and wait for the next new one close(connect_socket); return ESP_FAIL; } ESP_LOGI(TAG, "connect success!"); return ESP_OK; } |
TCP receive task code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | void recv_data(void *pvParameters) {undefined int len = 0; //length char databuff[1024]; //cache while (1) {undefined //Empty the cache memset(databuff, 0x00, sizeof(databuff)); //read received data len = recv(connect_socket, databuff, sizeof(databuff), 0); // exception flag g_rxtx_need_restart = false; if (len > 0) {undefined // print the received array ESP_LOGI(TAG, "recvData: %s", databuff); //Receive data back send(connect_socket, databuff, strlen(databuff), 0); } else {undefined // print error message show_socket_error_reason("recv_data", connect_socket); //Server failure, mark reconnection g_rxtx_need_restart = true;
break; } } close_socket(); // mark reconnection g_rxtx_need_restart = true; vTaskDelete (NULL); } |
TCP exception handling
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | static void tcp_connect(void *pvParameters) {undefined . . . . . . . while (1) {undefined vTaskDelay(3000 / portTICK_RATE_MS); //Re-create the client, the same as creating a new one if (g_rxtx_need_restart) {undefined vTaskDelay(3000 / portTICK_RATE_MS); ESP_LOGI(TAG, "reStart create tcp client..."); //create client int socket_ret = create_tcp_client(); if (socket_ret == ESP_FAIL) {undefined ESP_LOGE(TAG, "reStart create tcp socket error,stop..."); continue; } else {undefined ESP_LOGI(TAG, "reStart create tcp socket succeed..."); //Rebuild is complete, clear the flag g_rxtx_need_restart = false; //Create a tcp receive data task xTaskCreate(&recv_data, "recv_data", 4096, NULL, 4, &tx_rx_task); } } } vTaskDelete (NULL); } return ESP_OK; } |
Test process and effect display
test process
- Client test
- Change the account password of AP and STA
- #define TCP_SERVER_CLIENT_OPTION FALSE //esp32 as client
- Modify the IP (computer/mobile phone) and Port that connect to the server as a client
- Use a mobile phone or computer to use the assistant tool to establish a server, and let esp32 connect automatically
- Server test
- #define TCP_SERVER_CLIENT_OPTION TRUE //esp32 as server
- Modify the Port listened to when serving as a Server
- Mobile phone or computer directly connected to the AP of ESP32
- Use the TCP assistant tool as the Client to connect to the esp32 server
-
- Show results
-
Client effect display
Build the server first and wait for the ESP32 to come and connect.
test send data
pressure test
Server effect display
AP connected to ESP32
test send data
pressure test
test exception
Summary of TCP
- The bottom layer emphasizes the principle, and the application emphasizes the process + interface.
- The small pressure test does not lose packets, and the product stability should be measured in a large scale when transplanting by yourself.
- Source address: https://github.com/xiaolongba/wireless-tech
Click me -> more ESP32 development guide series catalog