ESP8266 Урок 17. Wi-Fi. STA. TCP Client



Продолжаем работать с приёмом и передачей данных по беспроводной сети Wi-Fi.

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

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

Схема наша по-прежнему не изменилась: отладочная плата, подключенная к ПК по USB

 

 

Проект был сделан из проекта урока 15 с именем ESPCONN_UDP_CLIENT и был назван, соответственно, ESPCONN_TCP_CLIENT_01. Постфикс _01 был применён в связи с тем, что у нас будет два проекта, незначительно отличающихся друг от друга.

Задача первого проекта — соединиться с сервером, передать ему пакет и сразу же от него отсоединиться.

Откроем проект в Eclipse и в файле user_config.h изменим имена следующих констант

 

#define TCPSERVERIP "192.168.1.76"

#define TCPSERVERPORT 30000

 

В файле main.c подключим заголовочный файл для работы с памятью

 

 

Переименуем функцию udp_connect в tcp_connect, удалив из неё практически всё тело. Оставим только объявление переменной и массива, имя которого тоже немного изменим, и переменной

 

static void ICACHE_FLASH_ATTR tcp_connect()

{

   uint32_t ip;

   char tcpserverip[15] = {};

}

Также изменим имя и в вызове данной функции в теле функции wifi_check_ip

 

tcp_connect();

 

Функцию udp_client_udp_send_cb переименуем в tcpclient_sent_cb

 

void ICACHE_FLASH_ATTR tcpclient_sent_cb(void* arg)

 

Выше добавим ещё одну функцию обратного вызова для обработки события разрыва соединения с сервером

 

 

А функцию udp_client_udp_recv_cb пока удалим совсем вместе с телом.

Вместо неё добавим другую функцию, которая будет служить функцией обратного вызова при событии соединения с сервером

 

 

В функции tcp_connect объявим переменную типа структуры espconn и выделим для неё память

 

 

 

Если сделать это не удалось, то выведем соответствующее сообщение в терминальную программу и покинем тело функции

 

 

Инициализируем тип и состояние соединения

 

 

Скопируем адрес сервера в символьный массив

 

 

Преобразуем строковое значение адреса сервера в целочисленное

 

 

Выделим память под поле структуры

 

 

Сгенерируем порт клиента и занесём его в соответствующее поле

 

 

А в поле порта сервера занесём значение из константы

 

 

Затем занесём в соответствующее поле сетевой адрес сервера

 

 

Зарегистрируем функцию обратного вызова события соединения с сервером

 

 

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

 

 

В данной функции обратного вызова tcpclient_connect_cb объявим символьный массив для передачи строки серверу

 

 

 

Объявим указатель на переменную структуры espconn, приравняв его адресу аргументов из первого параметра

 

 

Зарегистрируем функции обратного вызова обработки событий отправки пакета серверу и разрыва соединения с сервером

 

 

Отправим строку серверу, занеся её перед этим в символьный массив

 

 

В функции-обработчике отправки пакета также объявим указатель на переменную типа структуры espconn, присвоив ему адрес аргументов из входного параметра функции, оправим сообщение в терминальную программу и затем вызовем функцию разрыва соединения с сервером

 

 

В функции-обработчике завершения соединения с сервером мы также объявим указатель на переменную типа структуры espconn, присвоив ему адрес аргументов из входного параметра функции, очистим память структуры и поля tcp и выведем соответствующее сообщение в терминальной программе

 

 

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

 

 

Запустим WireShark, отфильтровавшись по адресу клиента, который мы также видим в терминальной программе.

Также запустим netcat, чтобы он начал слушать порт 30000

 

 

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

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

 

 

Также мы это видим и в терминальной программе

 

 

И также в программе WireShark мы можем наблюдать, как мы успешно соединились с клиентом, получили от него пакет и затем разъединились

 

 

Отлично!

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

Откроем наш новый проект и после функции tcpclient_sent_cb добавим ещё функцию-обработчик приёма пакетов TCP

 

 

В функции tcpclient_connect_cb зарегистрируем данную функцию обратного вызова

 

 

В функции tcpclient_sent_cb удалим вызов функции разрыва соединения с сервером

 

espconn_disconnect(pConn);

 

В функции-обработчике приёма пакета добавим переменную для вывода принятых символов в терминальную программу, а также объявим указатель на переменную типа структуры espconn, присвоив ему адрес аргументов из входного параметра функции

 

 

Отправим строку, принятую от сервера, посимвольно в терминальную программу и вызовем функцию разрыва соединения

 

 

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

 

 

 

 

Мы видим, что после передачи строки серверу соединение остаётся неразорванным.

Теперь попробуем передать строку клиенту в командной строке netcat

 

 

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

Также мы это можем заметить и по сообщениям в терминальной программе

 

 

В Wireshark мы также можем наблюдать, что после передачи пакета клиенту соединение было разорвано по инициативе клиента

 

 

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

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

 

 

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

 

Исходный код перового проекта

 

Исходный код второго проекта

 

 

Модуль ESP NodeMCU можно купить здесь: Модуль ESP NodeMCU

Различные модули ЕSP8266 можно приобрести здесь Модули ЕSP8266

Переходник USB to TTL можно приобрести здесь ftdi ft232rl

Многофункциональный переходник CJMCU FT232H USB к JTAG UART FIFO SPI I2C можно приобрести здесь ftdi ft232rl

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

 

 

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

 

ESP8266 Wi-Fi. STA. TCP Client

2 комментария на “ESP8266 Урок 17. Wi-Fi. STA. TCP Client
  1. Что то опять на исходный код ссылка не работает!

  2. YRabbit:

    #define TCPSERVERIP «192.168.100.176»

    static void ICACHE_FLASH_ATTR tcp_connect()
    {
    uint32_t ip;
    char tcpserverip[15] = {}; // <—- 15? Не нужно ли тут предусмотреть место для конечного нуля?

    os_sprintf(tcpserverip, "%s", TCPSERVERIP);

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

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

*