• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Как включить режим TCP_NODELAY?

Evgeniy932

New member
Привет!
Обнаружил неудобную особенность TCP<>UART моста - из-за разбивки пакетов часть данных доходит лишь со следующим пакетом.
Возможно ли на ESP8266 включить TCP_NODELAY?
 

pvvx

Активный участник сообщества
Что за TCP<>UART мост? На каком ПО?
В SDK используется LwIP.
У него есть макросы на СИ для переключения TCP_NODELAY для рабочей pcb:
tcp_nagle_disable(pcb);
tcp_nagle_enable(pcb);
 

Evgeniy932

New member
Использую вот эту прошивку:
https://esp8266.ru/forum/threads/proshivka-tcp2uart-perexodnika-s-nastrojkoj-po-web.146/

Если оправить в UART некоторое кол-во, то бывает что приходят не все отправленные.
НО! Если отправить ещё 1 байт - получаем все те, которые ранее не получили.

В коде увидел обработку прерывания UART_RXFIFO_TOUT_INT_ST, которое происходит вероятно после окончания приёма по таймауту?
Далее сбрасывается буфер через TCP.

Грешу на разбивку пакетов, как считаете, оно?
 

pvvx

Активный участник сообщества
Там стоит фиксированный тайм-аут (передается всё что успело залиться за 50 мс - это актуально для низких скоростей UART), или отправка при межсимвольной паузе типа в 4 символа, или при заполнении пакета TCP.
У вас что-то другое сбоит, т.к. описываемое вами условие в данные 3-и типа не входит.
 
Последнее редактирование:

Evgeniy932

New member
У меня модуль в режиме точки доступа, клиент - на WinAPI, блокирующие сокеты.
Может ли где-то здесь быть затык в настройках?
Совершено не понятна причина такого явления.

P.S. Код клиента только вечером смогу показать.
 

pvvx

Активный участник сообщества
WinAPI имеет опции отключения ожидания до выдачи подтверждения ACK для TCP в 200 мс.
https://support.microsoft.com/en-us/kb/214397
Представление:
Во время тестирования разработчик обнаруживает, что клиент может отправлять только пять записей в секунду на сервер. Всего 10000 записей, максимальный размер которых составляет 976 Кбайт данных (10000 * 100/1024), занимает более получаса для отправки на сервер. :)
 

Evgeniy932

New member
Может ли эта опция приводить к тому, что данные придут лишь вместе со следующей передачей по юарту?

Тогда я делал так:
1) Отправил 8192 байта
2) Получил меньше, чем отправлял (около 6500, не помню)
3) Отправил ещё 1 байт
4) Получил всё, что не получил на шаге 2 и ещё новые данные.
 

pvvx

Активный участник сообщества
Среднестатистически на WiFi из-за арбитража c AP и тормозного ESP8266 на отсылку одиночно следующего пакета (через паузы, хоть UDP) уходит от 20 мс. При постоянном приеме и передаче (дуплекс) ESP8266 на 160 МГц способен принять и передать к 800 пакетов в секунду. При этом задержка между передачей ему и получением ответа будет 1..2 мс. Но это когда идет непрерывный обмен.
Может ли эта опция приводить к тому, что данные придут лишь вместе со следующей передачей по юарту?

Тогда я делал так:
1) Отправил 8192 байта
2) Получил меньше, чем отправлял (около 6500, не помню)
3) Отправил ещё 1 байт
4) Получил всё, что не получил на шаге 2 и ещё новые данные.
8192/Maximum segment size — Википедия = ? Не кратно 2 x MSS.
Передав последний пакет ESP8266 начал ждать подтверждения приема. Но ваша программа его не дала - тормозит и думает о чём-то своем 200 мс.
Вы дали ещё байт. Он передался в новом пакете - четном. Тут ваша программа спохватилась и передала ACK на 2 последних пакета...
 
Последнее редактирование:

Evgeniy932

New member
Ага, 8192 не кратно, но как тогда обеспечить прозрачный UART<>TCP?
Неужели только по n*536 байт можно отправлять за раз?
 

pvvx

Активный участник сообщества
Ага, 8192 не кратно, но как тогда обеспечить прозрачный UART<>TCP?
Неужели только по n*536 байт можно отправлять за раз?
WinAPI имеет опции отключения ожидания до выдачи подтверждения ACK для TCP в 200 мс.
Далее всё по кругу. Обсуждать тут уже нечего. Описал с упрощениями. Есть масса тонкостей - они упущены...

Необходимо оптимизировать передачи. Но в ESP сделать это почти невозможно. LwIP не умеет бороться сам с этой бедой.
Проблема TCP у MS не является исключением. Её же Explorer отключает ожидание в 200 мс.
Gooogle Chrome и прочие - нет.
 
Последнее редактирование:

Evgeniy932

New member
Далее всё по кругу. Обсуждать тут уже нечего. Описал с упрощениями. Есть масса тонкостей - они упущены...

Необходимо оптимизировать передачи. Но в ESP сделать это почти невозможно. LwIP не умеет бороться сам с этой бедой.
Проблема TCP у MS не является исключением. Её же Explorer отключает ожидание в 200 мс.
Gooogle Chrome и прочие - нет.
Добрался до компа, запустил такую схему:

Wifi Client (WinAPI) <> ESP8266 <> USB-UART (FT232BM) <> комп 2

Отправляю запрос через TCP объемом 10 байт, принимаю на комп 2 и отправляю ответ - 1346 байт.
Клиент получает ответ и цикл повторяется.

Спустя 10 секунд клиент ловит Connection reset или срабатывает тайм-аут по приему на сокете.
Почему такое происходит? Могут ли это быть неверные настройки на TCP2UART?
 

nikolz

Well-known member
Далее всё по кругу. Обсуждать тут уже нечего. Описал с упрощениями. Есть масса тонкостей - они упущены...

Необходимо оптимизировать передачи. Но в ESP сделать это почти невозможно. LwIP не умеет бороться сам с этой бедой.
Проблема TCP у MS не является исключением. Её же Explorer отключает ожидание в 200 мс.
Gooogle Chrome и прочие - нет.
Если Вы говорите про алгоритм Nagle, то он отключается не в браузере, а в настройках винды.
Алгоритм Nagle — уменьшаем время доставки пакетов • 14 байт
 

Evgeniy932

New member
Сверху Снизу