Продолжаем работу с беспроводной сетью в режиме станции (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/ESP32-C3/ESP32-S3 можно купить здесь
Логический анализатор 16 каналов можно приобрести здесь
Дисплей LCD 20x4 можно приобрести тут
Дисплей LCD 16x2 можно приобрести тут
Переходник I2C to LCD1602 2004 можно приобрести здесь
Многофункциональный переходник CJMCU FT232H USB к JTAG UART FIFO SPI I2C можно купить здесь
Видео в Rutube
Видео в Дзен
Видео в Youtube