ESP32 Урок 24. Wi-Fi. STA. TCP Client. Соединение с сервером



Продолжаем работу с беспроводной сетью в режиме станции (STA) контроллера ESP32. И на данном уроке мы уже начнём работать с протоколом TCP (Transmission Control Protocol). Хотя, мы уже давно с данным протоколом работаем, изучили, можно сказать, его вдоль и поперёк. Мы знаем, что по сравнению с протоколом UDP данный протокол обладает рядом преимуществ — это его надёжность передачи данных, которая обеспечивается тем, что на каждый определённый участок данных требуется подтверждение от принимающей стороны, тем самым обеспечивается гарантированная доставка данных получателю, а также сохранение порядка следования сообщений. Конечно, надёжность эта достаётся не совсем дешевой ценой — нужно корректно создавать соединение с узлом, также корректно разъединяться, обеспечить подтверждение пакетов, следить за порядком следования сегментов и т.д. Но всё это нас не пугает, мы это изучили давным-давно, тем более, что часть данных забот возьмёт на свои плечи библиотека LWIP и её интерфейс SOCKET.

Схема наша также не изменилась и осталась такая же, как и в прошлом уроке

 

 

Так как протокол TCP не очень лёгкий, то работу с ним мы также разобьём на несколько уроков и в данном уроке мы создадим простой клиент, который пока только попытается создать соединение с сервером и затем его разорвать.

Проект был выполнен из проекта также прошлого урока с именем WIFI_STA_UDP_SERVER и получил новое имя WIFI_STA_TCP_CLIENT_CONNECT.

Откроем наш проект в Espressif IDE и переименуем файлы udp.h и udp.c соответственно в tcp.h и tcp.c, согласившись с переформированием ссылок на файлы

 

 

 

В файле CMakeLists.txt изменения вносим вручную

 

set(COMPONENT_SRCS "main.c wifi.c tcp.c i2c_user.c lcd2004.c")

 

В файле tcp.c функцию udp_task мы для порядка переименуем в tcp_task, не забывая также о её прототипе в заголовочном файле.

 

 

В функции app_main файла main.c также внесём соответствующее изменение в создании задачи

 

xTaskCreate(tcp_task, "tcp_task", 4096, NULL, 5, NULL);

 

Вернёмся в файл tcp.c и также для порядка изменим строку вывода в лог

 

static const char *TAG = "tcp";

В функции  удалим объявление следующей строки

char buf[10] = {};

 

А в этом символьном массиве увеличим количество элементов

 

char str1[21];

 

Изменим тип протокола в строке создания сокета

 

if ( (sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0 ) {

 

Следующий цикл удалим, но тело его оставим

 

xTaskCreate(vLCDTask, «vLCDTask», 2048, NULL, 2, &xLCDTaskHandle);
while(1)
{

  …….

}

 

Поэтому здесь удалим break

 

ESP_LOGE(TAG, «socket not created\n»);
break;

 

Вместо этого будет будет удаление задач и очереди

 

 

Вот эту строку с вычислением размера структуры также удалим

 

uint32_t client_addr_len = sizeof(cliaddr);

 

 

Заполним информацию о клиенте и свяжем сокет с адресом клиента

 

 

В следующей строке исправим инициализацию поля

 

servaddr.sin_addr.s_addr = inet_addr(CONFIG_SERVER_IP);

 

Чтобы не запутаться, после следующей строки удалим весь оставшийся код тела функции

 

servaddr.sin_port = htons(CONFIG_SERVER_PORT);

 

Попытаемся соединиться с сервером, если соединение прошло удачно, то выведем соответствующее сообщение на дисплей, затем подождём 2 секунды и попытаемся передать строку серверу, после чего подождём ещё 2 секунды

 

 

После попытки разрыва соединения выведем соответствующее сообщение на дисплей, а затем, подождав также пару секунд удалим задачи и очередь

 

 

Последние 2 секунды мы ждём для того, чтобы сообщение успело вывестись на дисплей до уничтожения задачи дисплея и очереди.

Вот и готов наш проект.

Но прежде чем его испытать, нам нужно сконфигурировать адрес и порт сервера, с которым мы будем пытаться соединяться.

Как узнать IP компьютера в сети, мы все знаем, поэтому узнаем его и данный адрес впишем и в конфигураторе, также впишем номера портов сервера и клиента

 

 

Соберём и прошьём нашу программу и узнаем сетевой адрес платы в терминале

 

 

Так как пока сервер не слушает порт, то мы получим соответствующее сообщение на нашем дисплее

 

 

Для начала на компьютере откроем Wireshark и настроим его на приём трафика только с адреса нашей платы

 

 

Затем запустим netcat и начнём слушать порт, назначенный нами в конфигураторе

 

 

Перезагрузим контроллер и, если всё правильно, то на дисплее мы сначала увидим следующее сообщение

 

 

Затем через 2 секунды в программе netcat мы увидим присланное сообщение

 

 

И ещё через 2 секунды на дисплее появится сообщение, сигнализирующее о разрыве соединения

 

 

Также весь процесс обмена мы можем наблюдать в Wireshark

 

 

Мы видим здесь, что соединение происходит корректно — путём трёхкратного рукопожатия, также обоюдно происходит и его разрыв.

Итак, на данном уроке нам удалось создать простейший TCP-клиент, который способен соединиться и разъединиться с сервером, а также передали на сервер пакет данных.

Всем спасибо за внимание!

 

Данная статья в Дзен.

 

 

Предыдущий урок Программирование МК ESP32 Следующий урок

 

Исходный код

 

 

Недорогие отладочные платы ESP32 можно купить здесь:

На AliExpress Недорогие отладочные платы ESP32

На Яндекс.Маркет Недорогие отладочные платы ESP32

Логический анализатор 16 каналов можно приобрести (AliExpress) здесь

Дисплей LCD 20×4 можно приобрести здесь (AliExpress) Дисплей LCD 20×4

Дисплей LCD 16×2 (AliExpress)

Переходник I2C to LCD можно приобрести здесь (AliExpress) I2C to LCD1602 2004

Дисплей символьный LCD 1602 с впаянным переходником на шину I2C (Яндекс.Маркет)

 

 

Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)

ESP32 Wi-Fi. STA. TCP Client. Соединение с сервером

 

Смотреть ВИДЕОУРОК в Дзен (нажмите на картинку)

ESP32 Wi-Fi. STA. TCP Client. Соединение с сервером

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*