서론
이번 글은 Zephyr ESP32 시리즈의 다섯 번째로 TCP 통신에 관한 것입니다. TCP/IP라고도 하며 Network의 대표적인 통신 방식입니다.
앞선 UDP 통신 실습에서는 ESP32와 PC 사이에서 데이터를 주고받는 기본적인 Network 통신을 확인하였습니다. 이번에는 TCP를 이용하여 ESP32와 PC 사이에 연결을 설정하고 데이터를 양방향으로 송수신해 보겠습니다.
ESP32를 Wi-Fi Network에 연결한 후 TCP Client로 동작하게 하고, PC에서 실행되는 TCP Server와 통신하는 것이 이번 글의 목표입니다.
TCP 통신 이란?
TCP(Transmission Control Protocol)는 Network에 연결된 두 장치 사이에서 데이터를 안정적으로 주고받기 위한 통신 Protocol입니다.
앞에서 실습한 UDP는 상대방과 미리 연결하지 않고 데이터를 전송합니다. 구조가 간단하고 빠르다는 장점이 있지만, 전송한 데이터가 상대방에게 제대로 도착했는지 또는 전송한 순서대로 도착했는지를 보장하지 않습니다.
TCP는 이와 달리 데이터를 전송하기 전에 먼저 상대방과 Connection을 설정합니다.
Connection이 설정된 후에는 데이터를 주고받으면서 데이터가 정상적으로 전달되었는지를 확인합니다. 전송 과정에서 데이터가 손실되면 다시 전송할 수 있으며, 여러 데이터가 전송된 경우에는 원래의 순서대로 전달될 수 있도록 처리합니다.
따라서 TCP의 중요한 특징은 다음과 같습니다.
- Connection-oriented
데이터를 전송하기 전에 통신 상대방과 Connection을 설정합니다. - Reliable transmission
데이터가 정상적으로 전달되었는지를 확인하며, 필요한 경우 다시 전송합니다. - Ordered delivery
전송된 데이터가 순서대로 전달되도록 합니다. - Bidirectional communication
Connection이 설정되면 양쪽에서 데이터를 송신하고 수신할 수 있습니다.
TCP Connection을 설정할 때에는 일반적으로 3-Way Handshake라고 하는 과정이 사용됩니다.
Client가 Server에 연결을 요청하는 SYN을 보내고, Server가 SYN + ACK로 응답한 후 Client가 다시 ACK를 보내면 TCP Connection이 설정됩니다.
여기서 SYN(Synchronize)은 TCP Connection을 시작하면서 데이터 전송에 사용되는 Sequence Number를 동기화하기 위한 제어 Flag이며, TCP 연결 요청의 시작을 의미합니다.
아래 그림에서 TCP 통신 과정을 설명하고 있습니다.

이러한 TCP의 연결 관리와 데이터 전송 처리는 TCP/IP Network Stack에서 담당합니다. 따라서 Application에서는 TCP Protocol의 세부 동작을 직접 구현하지 않고 Socket API를 이용하여 TCP 통신을 사용할 수 있습니다.
프로젝트 동작 구조
이번 프로젝트에서는 ESP32가 TCP Client, PC가 TCP Server로 동작합니다. ESP32와 PC는 Wi-Fi Network를 통해 연결되며, ESP32에서 PC의 IP Address와 TCP Port를 지정하여 Server에 연결합니다.
아래 그림은 앞에서 설명한 TCP의 Connection 설정 과정이 이번 프로젝트에서 Zephyr와 Python을 통해 어떻게 구현되는지를 보여줍니다.

ESP32 Application에서는 Zephyr의 Socket API를 이용하여 TCP Socket을 생성하고 connect()를 호출합니다.
그러면 Zephyr TCP/IP Network Stack과 PC의 TCP/IP Stack 사이에서 3-Way Handshake가 수행되어 TCP Connection이 설정됩니다.
PC에서는 Python으로 작성한 TCP Server를 실행합니다. Server는 지정된 Port에서 Client의 연결을 기다리며, ESP32가 연결을 요청하면 이를 받아들여 TCP Connection을 설정합니다.
TCP Connection이 설정된 후 ESP32에서는 send()와 recv()를 이용하여 PC와 데이터를 주고받습니다. PC Server에서도 동일한 Connection을 통해 ESP32로 데이터를 송신하거나 ESP32에서 전송한 데이터를 수신할 수 있습니다.
이번 프로젝트의 전체적인 동작 과정은 다음과 같습니다.
- ESP32가 Wi-Fi AP에 연결되고 IP Address를 할당받습니다.
- PC에서 Python TCP Server를 실행하여 Client의 연결을 기다립니다.
- ESP32에서 TCP Socket을 생성합니다.
- ESP32가
connect()를 호출하여 PC Server에 연결을 요청합니다. - Zephyr TCP/IP Network Stack과 PC의 TCP/IP Stack에서 3-Way Handshake가 수행됩니다.
- TCP Connection이 설정됩니다.
- 설정된 Connection을 통해 ESP32와 PC가 데이터를 양방향으로 송수신합니다.
TCP Connection이 설정된 후에는 하나의 연결을 유지하면서 여러 번 데이터를 주고받을 수 있습니다. 이번 프로젝트에서는 ESP32의 송신과 수신이 서로 영향을 주지 않도록 각각의 Thread에서 처리하도록 구성하였습니다.
따라서 앞 장에서 살펴본 TCP의 일반적인 Client → Connection 설정 → 양방향 Data 전송 구조가 이번 프로젝트에서는 ESP32/Zephyr → TCP Connection → PC/Python Server의 형태로 실제 구현됩니다.
Zephyr에서 제공하는 BSD Socket API와 TCP/IP Network Programming에 대한 자세한 내용은 [공식 문서]에서 확인할 수 있습니다.
프로젝트 생성 및 구성 파일 작성
이번 TCP 통신 프로젝트는 앞에서 실습한 Wi-Fi UDP 프로젝트를 기반으로 생성합니다.
기존 skpang_esp32_can_wifiudp 프로젝트를 복사한 후 프로젝트 이름을 다음과 같이 변경합니다.
skpang_esp32_can_wifitcp
Wi-Fi AP 연결과 DHCP를 이용한 IP Address 할당 과정은 UDP 실습과 동일하므로 기존 프로젝트의 설정을 그대로 사용하고, UDP 송수신 부분을 TCP Client 통신으로 변경합니다.
프로젝트는 다음과 같이 구성합니다.

main.c에서는 Wi-Fi AP 연결과 IP Address 할당을 처리하고, Network가 준비되면 TCP Client를 시작합니다.
TCP 통신에 관한 기능은 tcp_client.c와 tcp_client.h로 분리합니다. TCP Socket 생성, Server 연결 및 데이터 송수신을 별도의 파일로 구성함으로써 main.c가 지나치게 복잡해지는 것을 방지할 수 있습니다.
CMakeLists.txt
CMakeLists.txt에는 TCP Client 구현에 사용하는 Source File을 추가합니다.

이를 통해 main.c와 tcp_client.c가 함께 Build됩니다.
prj.conf
TCP 통신을 사용하기 위해서는 Zephyr의 Network 및 Socket 기능이 활성화되어 있어야 합니다.
Wi-Fi AP 연결 프로젝트에서 사용했던 Wi-Fi, Network, IPv4, DHCP 등의 설정은 그대로 사용합니다. 이번 프로젝트에서는 TCP Socket 통신에 필요한 TCP 기능을 활성화합니다.


CONFIG_NETWORKING은 Zephyr Network 기능을 활성화하고, CONFIG_NET_IPV4는 IPv4를 사용하도록 설정합니다.
CONFIG_NET_TCP는 TCP Protocol을 활성화하며, CONFIG_NET_SOCKETS는 Application에서 Socket API를 사용할 수 있도록 합니다.
Wi-Fi 연결과 DHCP에 필요한 기존 설정을 포함한 상태에서 이러한 Network 설정을 사용하면 ESP32 Application에서 TCP Socket을 생성하고 PC TCP Server와 통신할 수 있습니다.
이제 프로젝트의 기본 구성이 완료되었습니다. 다음 장에서는 tcp_client.c를 중심으로 ESP32 TCP Client의 실제 구현 과정을 살펴보겠습니다.
기존 Wi-Fi 프로젝트에서 사용한 Network 설정은 그대로 유지합니다. 이번 TCP 통신에서 중요한 설정은 CONFIG_NET_SOCKETS=y와 CONFIG_NET_TCP=y이며, 각각 Socket API와 TCP Protocol 기능을 활성화합니다.
CHANGELOG.md
이번 프로젝트의 CHANGELOG.md는 다음과 같습니다.


PC가 TCP Server로 동작하므로 ESP32의 TCP 연결을 받을 수 있도록 Windows Firewall에서 TCP Port 5000의 Inbound 통신을 허용해야 합니다. 해당 설정 방법은 CHANGELOG.md의 Notes에 추가하였습니다.
ESP32 TCP Client 구현
이번 프로젝트는 main.c와 tcp_client.c를 중심으로 구성됩니다.
main.c
main.c의 Wi-Fi 연결 부분은 앞의 실습에서 이미 자세히 다루었지만, 이번 TCP 프로젝트에서는 Wi-Fi 연결 이후 TCP Client가 시작되는 과정까지 하나의 흐름으로 이어지므로 전체 동작을 다시 한 번 정리해 보겠습니다.

위 그림에서 왼쪽 영역은 main()과 wifi_connect()에서 수행되는 초기 설정 과정이고, 오른쪽 영역은 Network Event가 발생한 후 Callback 함수에서 처리되는 과정을 나타냅니다.
먼저 main()에서는 기본 Network Interface를 가져오고 Wi-Fi 연결 결과와 IPv4 Address 할당을 확인하기 위한 Event Callback을 등록합니다.
iface = net_if_get_default();
이후 wifi_connect()를 호출하면 내부에서 NET_REQUEST_WIFI_CONNECT를 이용하여 Wi-Fi AP에 연결을 요청합니다.
이 시점에서 Wi-Fi Connection이 바로 완료되는 것은 아니며, 연결 결과는 Event를 통해 전달됩니다.
Wi-Fi 연결이 완료되면 NET_EVENT_WIFI_CONNECT_RESULT Event가 발생하고, 미리 등록해 둔 wifi_connect_handler()가 호출됩니다.
wifi_connect_handler()에서는 Wi-Fi 연결의 성공 여부를 확인합니다.
Wi-Fi가 정상적으로 연결된 후에는 DHCP를 통해 IPv4 Address를 할당받습니다. IPv4 Address가 Network Interface에 추가되면 NET_EVENT_IPV4_ADDR_ADD Event가 발생하고, 이에 대응하는 ipv4_addr_handler()가 호출됩니다.
ipv4_addr_handler()에서는 DHCP로 할당된 IPv4 Address를 확인하고 출력한 후 TCP Client를 시작합니다.
if (tcp_client_start() == 0) {
tcp_client_send("Hello from ESP32 TCP\n");
}
먼저 tcp_client_start()를 호출하여 PC TCP Server와 TCP Connection을 설정합니다.
TCP Connection이 정상적으로 설정되어 tcp_client_start()가 0을 반환하면, 이어서 tcp_client_send()를 호출하여 최초 Message를 PC Server로 전송합니다.
따라서 main.c의 전체적인 실행 흐름은 다음과 같이 정리할 수 있습니다.
Network Interface 획득 → Event Callback 등록 → Wi-Fi 연결 요청 → Wi-Fi 연결 Event → DHCP를 통한 IPv4 Address 할당 → IPv4 Event → TCP Client 시작 → 최초 Data 송신
여기서 중요한 점은 Wi-Fi 연결과 IPv4 Address 할당, TCP 연결이 한 번에 이루어지는 것이 아니라 각각의 단계가 완료된 후 다음 단계로 진행된다는 것입니다.
특히 TCP Client는 Wi-Fi에 연결된 직후가 아니라 DHCP를 통해 IPv4 Address가 할당된 것이 확인된 후 시작됩니다.
이와 같이 main.c는 Network가 TCP 통신을 할 수 있는 상태가 될 때까지의 과정을 관리하고, 실제 TCP Socket 생성과 Server Connection, Data 송수신은 tcp_client.c에서 처리하도록 구성되어 있습니다.
아래는 main.c의 전체 코드 입니다.
.





tcp_client.c
실제 TCP 통신 기능은 tcp_client.c에서 구현합니다.
tcp_client.c에서는 TCP Socket을 생성하고 PC의 TCP Server에 연결한 후, 데이터를 송수신합니다. 또한 PC에서 전송되는 데이터를 계속 수신할 수 있도록 별도의 Receive Thread를 사용합니다.
아래는 tcp_client.c 의 동작 흐름도 입니다.

TCP Connection 설정과 Receive Thread 생성
앞의 main.c에서 IPv4 Address가 할당되면 ipv4_addr_handler()에서 tcp_client_start()를 호출합니다.
tcp_client_start()에서는 먼저 zsock_socket()을 이용하여 TCP Socket을 생성하고, PC TCP Server의 IP Address와 Port를 설정합니다. 이후 zsock_connect()를 호출하여 PC TCP Server에 Connection을 요청합니다.
zsock_connect()가 정상적으로 완료되면 ESP32와 PC 사이에 TCP Connection이 설정됩니다.
앞에서 살펴본 3-Way Handshake와 같은 TCP Connection 설정 과정은 Application에서 직접 처리하지 않고 TCP/IP Stack에서 처리하므로, 프로그램에서는 zsock_connect()를 호출하여 TCP Server와의 연결을 요청하면 됩니다.
TCP Connection이 설정된 후에는 k_thread_create()를 이용하여 별도의 Receive Thread를 생성합니다.
새로 생성된 Receive Thread에서는 tcp_rx_thread_entry()가 실행되며, 이 함수 내부의 zsock_recv()에서 PC로부터 전송되는 데이터를 기다립니다.
zsock_recv()는 데이터가 수신될 때까지 대기하고, 데이터가 수신되면 이를 처리한 후 다시 zsock_recv()를 호출합니다. 따라서 그림의 왼쪽과 같이 Receive Thread에서는 TCP 데이터 수신 과정이 반복됩니다.
TCP 송신
Receive Thread를 생성한 후에도 기존 프로그램의 실행 흐름은 계속됩니다.
tcp_client_start()가 정상적으로 완료되면 0을 반환하고, 프로그램은 이를 호출했던 ipv4_addr_handler()로 복귀합니다.
앞의 main.c에서 살펴본 것처럼 다음 코드가 실행됩니다.
if (tcp_client_start() == 0) {
tcp_client_send("Hello from ESP32 TCP\n");
}
따라서 tcp_client_start()가 성공하면 이어서 tcp_client_send()가 호출됩니다.
tcp_client_send()에서는 zsock_send()를 이용하여 이미 설정된 TCP Connection을 통해 데이터를 PC TCP Server로 전송합니다.
이 구조에서 중요한 점은 TCP 수신과 송신의 실행 흐름이 분리되어 있다는 것입니다.
Receive Thread는 zsock_recv()에서 PC로부터 전달되는 데이터를 계속 기다리는 반면, 기존 실행 흐름에서는 tcp_client_send()를 이용하여 데이터를 전송할 수 있습니다.
따라서 TCP Connection이 설정된 이후의 전체 흐름은 다음과 같이 정리할 수 있습니다.
TCP Socket 생성 → TCP Server Connection → Receive Thread 생성 → 수신 대기
동시에 기존 실행 흐름에서는
tcp_client_start() 완료 → ipv4_addr_handler() 복귀 → tcp_client_send() → TCP Data 송신
으로 진행됩니다.
이와 같이 별도의 Receive Thread를 사용함으로써 zsock_recv()가 데이터를 기다리는 동안에도 다른 프로그램의 실행을 막지 않고 TCP 송수신을 처리할 수 있습니다.
아래는 tcp_client.c의 전체 코드입니다.





PC TCP Server 구현
PC TCP Server는 Python 프로그램으로 구현합니다.
이번 실습의 중심은 ESP32에서 Zephyr Socket API를 이용하여 TCP Client를 구현하는 것이므로, PC TCP Server의 Python 코드에 대해서는 전체적인 동작 구조만 간단히 살펴보겠습니다.
PC Server는 TCP Port 5000에서 ESP32 Client의 Connection을 기다리고, 연결이 설정되면 ESP32와 데이터를 양방향으로 송수신합니다.
데이터의 수신과 키보드를 통한 송신이 서로 영향을 주지 않도록 receive_thread()와 send_thread() 두 개의 Thread를 사용합니다. receive_thread()는 ESP32에서 전송되는 데이터를 계속 수신하고, send_thread()는 사용자가 입력한 Message를 ESP32로 전송합니다.
전체 프로그램은 다음과 같습니다.



코드의 기본적인 동작 흐름은 다음과 같습니다.
socket() → bind() → listen() → accept() → TCP Connection → Data 송수신
Server는 socket()으로 TCP Socket을 생성하고 bind()를 이용하여 Port 5000에 연결합니다. 이후 listen() 상태에서 Client의 Connection을 기다리며, ESP32가 연결을 요청하면 accept()를 통해 TCP Connection을 설정합니다.
Connection이 설정된 후에는 receive_thread()에서 ESP32가 전송하는 데이터를 수신하고, send_thread()에서는 사용자가 입력한 데이터를 ESP32로 전송합니다.
또한 ESP32와의 Connection이 끊어지면 Server는 다시 accept()에서 새로운 Connection을 기다리도록 구성하였습니다. 따라서 ESP32를 Reset하거나 TCP Connection이 다시 설정되는 경우에도 Server 프로그램을 다시 실행할 필요 없이 새로운 연결을 받을 수 있습니다.
빌드 및 실행
이제 프로젝트를 빌드하고 실제 TCP 통신을 확인해 보겠습니다.
지금까지의 프로젝트와 마찬가지로 CHANGELOG.md에 기록해 둔 빌드 명령을 사용합니다. Terminal의 현재 Directory는 프로젝트 Directory로 이동한 상태에서 실행합니다.
빌드 명령은 다음과 같습니다.
![]()
빌드가 정상적으로 완료되면 ESP32에 Firmware를 Flash 합니다.

ESP32를 실행하기 전에 PC에서는 앞에서 작성한 Python TCP Server를 실행합니다.
python tools/tcp_server_4.py
PC TCP Server는 Port 5000에서 ESP32의 Connection을 기다립니다.
ESP32가 실행되면 먼저 Wi-Fi AP에 연결되고 DHCP를 통해 IPv4 Address를 할당받습니다. 이후 tcp_client_start()가 실행되어 PC TCP Server에 Connection을 요청합니다.
TCP Connection이 정상적으로 설정되면 ESP32에서는 다음과 같은 순서로 동작합니다.
Wi-Fi 연결 → IPv4 Address 할당 → TCP Server 연결 → TCP Connection 설정 → 최초 Message 송신
PC Server에서는 ESP32가 전송한 "Hello from ESP32 TCP" Message를 확인할 수 있습니다.
이후 PC에서 Message를 입력하면 ESP32의 Receive Thread에서 이를 수신할 수 있으며, 하나의 TCP Connection을 통해 ESP32와 PC 사이의 양방향 TCP 통신이 이루어지는 것을 확인할 수 있습니다.
아래 tcp_server_4.py를 실행시킨 화면입니다.

아래는 Docklite로 본 ESP32의 Cosole화면입니다.

먼저 PC에서 tcp_server_4.py를 실행하면 TCP Server가 Port 5000에서 ESP32 Client의 Connection을 기다립니다.
ESP32가 실행되면 Wi-Fi AP에 연결한 후 DHCP를 통해 IPv4 Address를 할당받고, 이어서 PC TCP Server의 IP Address와 Port 5000으로 TCP Connection을 요청합니다.
PC Server 화면에서 다음과 같이 ESP32 Client가 연결된 것을 확인할 수 있습니다.
Client connected: ('192.168.0.9', 45929)
192.168.0.9는 ESP32에 할당된 IPv4 Address이며, 45929는 이번 TCP Connection에서 ESP32 측에 사용된 Source Port입니다.TCP Connection이 설정되면 ESP32의 tcp_client_start()가 정상적으로 완료되고, 이어서 tcp_client_send()가 실행되어 최초 Message를 PC로 전송합니다.
따라서 PC Server에서는 다음 Message가 수신됩니다.
Received: Hello from ESP32 TCP
Wi-Fi connected
IPv4 address: 192.168.0.9
Connecting to TCP server 192.168.0.6:5000...
TCP connected
TCP TX: Hello from ESP32 TCP
또한 PC Server 화면에는 ESP32가 다시 연결되면서 Client의 Source Port가 45929에서 34640으로 변경된 것도 볼 수 있습니다. TCP Connection이 새로 만들어질 때 Client 측 Source Port는 달라질 수 있지만, Server는 계속 지정된 Port 5000에서 Connection을 기다립니다.
여기까지의 결과를 통해 ESP32 TCP Client가 PC TCP Server에 정상적으로 연결되고 ESP32 → PC 방향의 TCP Data 송신이 이루어지는 것을 확인하였습니다.
다음으로는 PC Server에서 Message를 전송하여, 별도의 Receive Thread에서 동작하고 있는 ESP32의 zsock_recv()가 데이터를 정상적으로 수신하는지 확인합니다.
아래는 PC에서 세번 “Hi! from PC 1”, “Hi! from PC 2”, “Hi! from PC 3” 라는 Message를 보낸 화면입니다.

아래는 ESP32에서 수신한 화면입니다.

PC Server의 send_thread()에서 입력한 Message는 이미 설정되어 있는 TCP Connection을 통해 ESP32로 전송됩니다.
ESP32에서는 앞에서 생성한 별도의 Receive Thread가 zsock_recv()를 실행하며 수신 Data를 기다리고 있습니다. PC에서 Message가 전송되면 zsock_recv()가 이를 수신하고 Console에 출력합니다.
위 ESP32 Console 화면에서 다음과 같이 PC에서 전송한 세 개의 Message가 모두 수신된 것을 확인할 수 있습니다.
TCP RX: Hi! from PC 1
TCP RX: Hi! from PC 2
TCP RX: Hi! from PC 3
Message를 하나 수신한 후에도 Receive Thread는 종료되지 않고 다시 zsock_recv()를 실행하여 다음 Data를 기다립니다. 따라서 PC에서 여러 번 Message를 전송해도 ESP32에서는 계속해서 데이터를 수신할 수 있습니다.
이로써 하나의 TCP Connection을 통해 ESP32 → PC 송신뿐만 아니라 PC → ESP32 수신도 정상적으로 동작하는 것을 확인하였습니다.
즉, 이번 실습에서 구현하고자 했던 ESP32와 PC 사이의 양방향 TCP 통신이 정상적으로 이루어지고 있음을 확인할 수 있습니다.
UDP와 TCP 비교
앞의 UDP 실습과 이번 TCP 실습에서는 모두 ESP32와 PC가 Wi-Fi Network를 통해 데이터를 송수신하였습니다.
UDP에서는 별도의 Connection 설정 없이 상대방의 IP Address와 Port를 지정하여 바로 데이터를 송수신할 수 있습니다. 반면 TCP에서는 데이터를 송수신하기 전에 먼저 Client와 Server 사이에 Connection을 설정해야 합니다.
이번 실습에서도 ESP32는 zsock_connect()를 이용하여 PC TCP Server와 Connection을 설정한 후, zsock_send()와 zsock_recv()를 통해 데이터를 송수신하였습니다.
두 Protocol의 주요 차이를 정리하면 다음과 같습니다.
| 항목 | UDP | TCP |
|---|---|---|
| 통신 방식 | Connectionless | Connection-oriented |
| Connection 설정 | 필요 없음 | 필요 |
| 데이터 형태 | Datagram | Byte Stream |
| 주요 송수신 API | sendto(), recvfrom() |
send(), recv() |
| 데이터 전달 | 전달 및 순서 보장 없음 | 신뢰성 및 순서 보장 |
| 통신 구조 | 비교적 단순 | 상대적으로 복잡 |
| 통신 부하 | 비교적 작음 | 상대적으로 큼 |
UDP는 구조가 단순하고 Overhead가 작은 반면, TCP는 Connection을 유지하면서 데이터의 순서와 신뢰성 있는 전달을 제공합니다.
따라서 어느 Protocol이 더 좋은가의 문제가 아니라, Application에서 요구하는 통신 특성에 따라 UDP와 TCP를 선택하는 것이 중요합니다.
이번 두 실습을 통해 UDP와 TCP의 차이를 이론뿐만 아니라 Socket API와 실제 프로그램의 동작 구조를 통해 직접 확인할 수 있었습니다.
결론
이번 실습에서는 ESP32를 TCP Client, PC를 TCP Server로 구성하여 Wi-Fi Network를 통한 양방향 TCP 통신을 구현하였습니다.
Wi-Fi 연결과 IPv4 Address 할당 이후 TCP Client가 시작되는 전체 흐름을 살펴보았으며, Zephyr Socket API를 이용한 TCP Connection 설정과 별도의 Receive Thread를 이용한 데이터 수신 과정도 확인하였습니다.
앞의 UDP 실습과 이번 TCP 실습을 통해 ESP32에서 Network 통신이 어떻게 이루어지는지와 두 Protocol의 차이를 실제 프로그램을 통해 확인할 수 있었습니다.
다음 실습에서는 이러한 Network 통신을 기반으로 MQTT Protocol을 사용하여 ESP32와 MQTT Broker 사이에서 Message를 송수신하는 방법을 살펴보겠습니다.