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

Web сервер. Не хватает сокетов.

IBAH

New member
Замыслил в приборе простенький веб-интерфейс.
Использовал ESP-01 (v3.0.5), как точка доступа, настроил и сохранил.
Поднял на своем МК неблокирующий ТСР интерфейс через АТ команды.
Написал неблокирующий Веб-сервер.
Написал страничку, 4 гифки + 2 фрейма. Почему так. Страничку толстая храним во флеше, а переписываем только фреймы, хранящиеся в ОЗУ.
Столкнулся с нехваткой сокетов!!!
Когда использую интерфейс на 5 сокетов более менее работает, и то не всегда, иногда один файл грузится с ошибкой.
При 3 разрешенных сокетах, вообще все плохо.
Почему борюсь за количество сокетов. Каждый сокет требует 2кбайта итого 3*2=6к+ 2к на уарт, итого 8к для уже меня расточительно)

Снифером изучил обмен пакетами (браузер FireFox, режим KeepAlive ):

23 TCP 192.168.0.101 192.168.0.1 50315 80 http 22 3 722 Bytes 5 050 Bytes 31.10.2024 19:06:36:794 31.10.2024 19:06:45:784 00:00:08.989
24 TCP 192.168.0.101 192.168.0.1 50316 80 http 24 4 040 Bytes 5 396 Bytes 31.10.2024 19:06:37:440 31.10.2024 19:06:46:533 00:00:09.092
25 TCP 192.168.0.101 192.168.0.1 50317 80 http 14 2 391 Bytes 3 347 Bytes 31.10.2024 19:06:37:440 31.10.2024 19:06:45:032 00:00:07.592
//запрос zn1.htm ошибка
26 TCP 192.168.0.101 192.168.0.1 50318 80 http 7 445 Bytes 1 210 Bytes 31.10.2024 19:06:37:468 31.10.2024 19:06:37:479 00:00:00.011
27 TCP 192.168.0.101 192.168.0.1 50319 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:37:481 31.10.2024 19:06:37:490 00:00:00.009
28 TCP 192.168.0.101 192.168.0.1 50320 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:37:492 31.10.2024 19:06:37:519 00:00:00.027
29 TCP 192.168.0.101 192.168.0.1 50321 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:37:522 31.10.2024 19:06:37:526 00:00:00.004
30 TCP 192.168.0.101 192.168.0.1 50322 80 http 7 445 Bytes 1 210 Bytes 31.10.2024 19:06:37:529 31.10.2024 19:06:37:538 00:00:00.009
31 TCP 192.168.0.101 192.168.0.1 50323 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:37:541 31.10.2024 19:06:37:547 00:00:00.006
32 TCP 192.168.0.101 192.168.0.1 50324 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:37:551 31.10.2024 19:06:37:556 00:00:00.005
33 TCP 192.168.0.101 192.168.0.1 50325 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:37:558 31.10.2024 19:06:37:563 00:00:00.005
34 TCP 192.168.0.101 192.168.0.1 50326 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:37:566 31.10.2024 19:06:37:571 00:00:00.005
35 TCP 192.168.0.101 192.168.0.1 50327 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:37:595 31.10.2024 19:06:37:595 00:00:00.000
//запрос gif4.gif ошибка
36 TCP 192.168.0.101 192.168.0.1 50328 80 http 7 356 Bytes 1 032 Bytes 31.10.2024 19:06:38:100 31.10.2024 19:06:38:107 00:00:00.007
37 TCP 192.168.0.101 192.168.0.1 50329 80 http 5 356 Bytes 952 Bytes 31.10.2024 19:06:38:110 31.10.2024 19:06:38:114 00:00:00.004
38 TCP 192.168.0.101 192.168.0.1 50330 80 http 5 356 Bytes 952 Bytes 31.10.2024 19:06:38:127 31.10.2024 19:06:38:127 00:00:00.000
39 TCP 192.168.0.101 192.168.0.1 50331 80 http 7 356 Bytes 1 032 Bytes 31.10.2024 19:06:38:128 31.10.2024 19:06:38:142 00:00:00.014
40 TCP 192.168.0.101 192.168.0.1 50332 80 http 5 356 Bytes 952 Bytes 31.10.2024 19:06:38:143 31.10.2024 19:06:38:147 00:00:00.004
41 TCP 192.168.0.101 192.168.0.1 50333 80 http 7 356 Bytes 1 032 Bytes 31.10.2024 19:06:38:150 31.10.2024 19:06:38:159 00:00:00.009
42 TCP 192.168.0.101 192.168.0.1 50334 80 http 5 356 Bytes 952 Bytes 31.10.2024 19:06:38:160 31.10.2024 19:06:38:166 00:00:00.006
43 TCP 192.168.0.101 192.168.0.1 50335 80 http 5 356 Bytes 952 Bytes 31.10.2024 19:06:38:169 31.10.2024 19:06:38:174 00:00:00.005
44 TCP 192.168.0.101 192.168.0.1 50336 80 http 5 356 Bytes 952 Bytes 31.10.2024 19:06:38:178 31.10.2024 19:06:38:182 00:00:00.004
45 TCP 192.168.0.101 192.168.0.1 50337 80 http 5 356 Bytes 952 Bytes 31.10.2024 19:06:38:185 31.10.2024 19:06:38:194 00:00:00.009
// запрос zn2.htm ошибка
46 TCP 192.168.0.101 192.168.0.1 50338 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:38:255 31.10.2024 19:06:38:257 00:00:00.002
47 TCP 192.168.0.101 192.168.0.1 50339 80 http 7 445 Bytes 1 210 Bytes 31.10.2024 19:06:38:260 31.10.2024 19:06:38:276 00:00:00.016
48 TCP 192.168.0.101 192.168.0.1 50340 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:38:277 31.10.2024 19:06:38:285 00:00:00.008
49 TCP 192.168.0.101 192.168.0.1 50341 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:38:288 31.10.2024 19:06:38:298 00:00:00.010
50 TCP 192.168.0.101 192.168.0.1 50342 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:38:299 31.10.2024 19:06:38:304 00:00:00.005
51 TCP 192.168.0.101 192.168.0.1 50343 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:38:306 31.10.2024 19:06:38:312 00:00:00.006
52 TCP 192.168.0.101 192.168.0.1 50344 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:38:313 31.10.2024 19:06:38:320 00:00:00.007
53 TCP 192.168.0.101 192.168.0.1 50345 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:38:321 31.10.2024 19:06:38:326 00:00:00.005
54 TCP 192.168.0.101 192.168.0.1 50346 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:38:328 31.10.2024 19:06:38:376 00:00:00.048

55 TCP 192.168.0.101 192.168.0.1 50347 80 http 5 445 Bytes 1 130 Bytes 31.10.2024 19:06:38:377 31.10.2024 19:06:38:377 00:00:00.000

Что я вижу. Браузер долбится в закрытую дверь 10 раз с интервалом ~10мс, а переспросить по другому соединению не догадывается . По первым трем соединениям выкачивает, остальные три файла становятся в ошибку.
Как только на загрузку попадают файлы, а имеющиеся соединения заняты. браузер начинает долбится, и если соединение освободится до того как исчерпается долбежка, загрузка пройдет нормально. Иначе загружаемый файл станет в ошибку NS_ERROR_NET_RESET. ЕСП слишком медленная, браузер гораздо быстрее. И он успевает поставить на запросе крест.

Пробовал режим ConnectionClose, там те же самые проблемы.

Что делать?
Вижу один выход. Делать закачку контента скриптом?
Может еще есть варианты?
 

pvvx

Активный участник сообщества
С пол сотни одновременно открытых TCP хватит?
У любой ESP с современными браузерами будут беды для любого варианта многопользовательского WEB. Не хватает памяти и производительность желательна побольше...
Да даже для однопользовательского...

Нагрузку WEB проверять можно c помощью Jmeter установив хоть эмуляцию сотни клиентов.

Что и почему раскидано по форуму, давно всё это было в 2017г... ESP32 - полный аутсайдер.
Победил RTL8195 и аналоги с 2МБ RAM. Для обслуживания пару TCP сокетов по стандарту памяти не может быть менее 1..2 МБ, тем более для WEB.

кусок --->
 

rst

Member
Замыслил в приборе простенький веб-интерфейс.
...
Может еще есть варианты?
Количество доступных открытых сокетов не имеет никакого отошение к работоспособности WEB-сервера. Он может работать хоть на одном доступном сокете. Вне зависимости от того - сколько картинок или чего другого на страничке. При одном сокете все файлы со странички просто запрашиваются последовательно, один за другим, а не параллельно.
Также к работоспособности WEB-сервера не имеет никакого отношения режим "Connection: close" или "Connection: keep-alive". WEB работает хоть закрывая/переоткрывая сокет для каждого файла; хоть без закрытия сокета между файлами.

Ищите ошибку в своей реализации сервера.
 

IBAH

New member
Количество доступных открытых сокетов не имеет никакого отошение к работоспособности WEB-сервера. Он может работать хоть на одном доступном сокете. Вне зависимости от того - сколько картинок или чего другого на страничке. При одном сокете все файлы со странички просто запрашиваются последовательно, один за другим, а не параллельно.
Также к работоспособности WEB-сервера не имеет никакого отношения режим "Connection: close" или "Connection: keep-alive". WEB работает хоть закрывая/переоткрывая сокет для каждого файла; хоть без закрытия сокета между файлами.

Ищите ошибку в своей реализации сервера.
Количество открытых сокетов ни имеет никакого отношения к работоспособности WEB-сервера! оно имеет отношение к работоспособности браузера!
Браузер хочет много соединений. ESP его отфутболивает, причем жестко!

Как объяснил один гуру ТСР :
В нормальном стеке с ограничением сокетов выглядит так. Если не хватает сокетов то на SYNC клиента сервер не отвечает а клиент делает ретрансмисию через определенное время. Как только на стороне сервера появляется свободный сокет, то сервер дает ACK.
Если бы в 8266 работало так то никаких проблем с тем , что клиент выдает запросы параллельно (скорей всего не было бы даже ретрансмисии ). В данном случае скорей всего сервер дает RESET. Подозреваю, что стек в 8266 не поддерживает ретрансмисию. В локальной сети как-то еще будет работать, но через интернет будет глючить.
8266 буду обходить стороной :)



Проблему я решил организацией странички. Гружу последовательно скриптом. Браузер все тянет через один сокет.
 

rst

Member
Количество открытых сокетов ни имеет никакого отношения к работоспособности WEB-сервера! оно имеет отношение к работоспособности браузера!
Браузер хочет много соединений.
Бред. Делал проекты с веб-сервером на одном сокете. Всё работало нормально. И с разными браузерами. Какая разница чего там хочет браузер? Сколько сервер откроет соединений, по стольки браузер и будет работать.
 

IBAH

New member
Бред. Делал проекты с веб-сервером на одном сокете. Всё работало нормально. И с разными браузерами. Какая разница чего там хочет браузер? Сколько сервер откроет соединений, по стольки браузер и будет работать.
Я привел логи снифера. Правда форум их немного искалечил, но понять можно.
Как только на загрузку попадают файлы, а имеющиеся соединения заняты. браузер начинает долбится в закрытую дверь, и если соединение освободится до того как исчерпается долбежка, загрузка пройдет нормально, через освободившееся соединение. Иначе загружаемый файл станет в ошибку NS_ERROR_NET_RESET. ЕСП слишком медленная, браузер гораздо быстрее. И он успевает поставить на запросе крест.

Фаирфокс умеет ограничивать количество соединений, есть настройка network.http.max-connections.

Фаирфокс еще по-божески, а вот Интернет Эксплоер после первого отфутболивания попытки соединения становится в ошибку Aborted
 

IBAH

New member
Я привел логи снифера. Правда форум их немного искалечил, но понять можно.
Как только на загрузку попадают файлы, а имеющиеся соединения заняты. браузер начинает долбится в закрытую дверь, и если соединение освободится до того как исчерпается долбежка, загрузка пройдет нормально, через освободившееся соединение. Иначе загружаемый файл станет в ошибку NS_ERROR_NET_RESET. ЕСП слишком медленная, браузер гораздо быстрее. И он успевает поставить на запросе крест.

Фаирфокс умеет ограничивать количество соединений, есть настройка network.http.max-connections.

Фаирфокс еще по-божески, а вот Интернет Эксплоер после первого отфутболивания попытки соединения становится в ошибку Aborted
смотрите внимательно логи там все видно
первое соединение существует 19:06:36:794 - 19:06:45:784 , это закачка + таймаут соединения (5 секунд)
второе 19:06:37:440 - 19:06:46:533
третье 19:06:37:440 - 19:06:45:032

а в 19:06:37:468 браузер начинает долбится в четвертое соединение, которого нет. долбится 10 раз через приблизительно 10мс.
и к 19:06:37:595 перестает долбится. А доступные соединения то заняты.... браузер выкидывает ошибку
 

pvvx

Активный участник сообщества
Количество доступных открытых сокетов не имеет никакого отошение к работоспособности WEB-сервера. Он может работать хоть на одном доступном сокете. Вне зависимости от того - сколько картинок или чего другого на страничке. При одном сокете все файлы со странички просто запрашиваются последовательно, один за другим, а не параллельно.
Также к работоспособности WEB-сервера не имеет никакого отношения режим "Connection: close" или "Connection: keep-alive". WEB работает хоть закрывая/переоткрывая сокет для каждого файла; хоть без закрытия сокета между файлами.

Ищите ошибку в своей реализации сервера.
Нашел - он закрывает соединение, но не отслеживает состояние TIME_WAIT.
Т.е. быстро и без ошибок ESP WEB не работает - читайте стандарты RFC про TIME_WAIT для TCP.
Но если вас утраивает загрузка страницы с десятком файлов за час - это ваше дело. Т.е. вы предлагаете такое решение - поставить десятисекундные таймауты на открытие сокета и отдавать данные по десть байт в секунду ?
 

rst

Member
Т.е. вы предлагаете такое решение - поставить десятисекундные таймауты на открытие сокета и отдавать данные по десть байт в секунду ?
Я предлагаю вам почитать учебники по HTTP. В частности - что такое и как работает: "keep-alive".
Прежде чем писать очередной вздор.
Также советую прочитать - что такое и зачем нужен TIME_WAIT. О котором вы что-то слышали, но как видно - совершенно ничего не поняли.

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

Работаю с ESP8266 давно. Сказки про некие "тормоза" с открытием/закрытием TCP-соединения оставьте для болванов.
 

pvvx

Активный участник сообщества
...
и к 19:06:37:595 перестает долбится. А доступные соединения то заняты.... браузер выкидывает ошибку
Браузер открывает сразу 5 соединений на одну страницу в надежде на многопоточность. Тем более если найдет в HTML подгрузку других файлов. И не важно - одно соединение с keep-alive (пустое) он держит практически вечно, пока страница открыта.
Ранее это дело у браузеров пресекалось путем открытия WEB не на 80-м порту, а с другим номером. Но что сейчас у них там - не смотрел.
 

pvvx

Активный участник сообщества
Я предлагаю вам почитать учебники по HTTP. В частности - что такое и как работает: "keep-alive". Прежде чем писать очередной вздор.

И советую не придумывать за других их мысли. Тем более так тупо.
Вы о чем? Я вам написал о простом TCP/IP. До работы WEB/HTTP с вами разговора ещё не дошло.
Дополнение для вашего учения - у LwIP структура TCP сокета занимает не менее 200 байт в ESP. Далее смотрите что такое TCP в состоянии TIME_WAIT. И решите задачу, сколько таких TCP сможет удержать и отработать таймерами ESP.
Когда решите - перейдем к поведению браузеров и всяких HTTP стандартов...
 

pvvx

Активный участник сообщества
И что?
А сила тяжести на Луне в 6 раз меньше земной. Только какое это имеет отношение к web-серверу в МК автора?
Т.е. вы не шарите в простом TCP/IP, а уже лезете в HTTP?
Даю пример - включили ESP, оно создает соединение по порту N, а запросивший пересылает TCP Abort и полосочки в Wireshark становятся красненькими, т.к. рандом у ESP никудышный и она хочет соединения по прошлому номеру своего порта и собеседника. IP у них не менялись :p Чтобы этого не было, нужно перезагружать ESP с паузой не менее 200 секунд. Это и есть таймаут TCP в состоянии TIME_WAIT, от которого на больших серверах применяется не LwIP, т.к. портов всего 65535 а отслеживать полные IP:port свои и клиентов он не умеет (урезан). Даже на простых машинах это беда с нормальными стеками TCP и применяются не тривиальные решения...
 

pvvx

Активный участник сообщества
В ESP TIME_WAIT вырезан напрочь. Патчем LwIP.
Соответственно необходимо ограничить таймаутами возможность перебора выделенной области для TCP портов соединений, чтобы за 200 секунд этот выделенный объем уже закрытых соединений не исчерпывался.
Т.е. ESP необходимо тупить и как можно чаще, иначе бяда с TCP.
Это запросто возможно в Arduino, т.к. оно и так тупит само.
 

pvvx

Активный участник сообщества
Если ESP не отрабатывает deep-sleep, то TCP может спасти роутер с ограничением полосы к ESP и всякими настройками файрволов типа против DDOS...
Т.е. тупить и тупить задержками. Иначе на ESP никак.
@rst - вам всё равно WEB на ESP нужен для мигания светодиодом раз в час. По этому вы не сталкивались с обрезками всего в ESP и несоответствиями стандартам TCP.
В IoT поделках давно не ставят WEB на ESP, а пользуют одиночный тормозной сокет.
 

pvvx

Активный участник сообщества
И что?
А сила тяжести на Луне в 6 раз меньше земной. Только какое это имеет отношение к web-серверу в МК автора?
Наипростейшее отношение:
1. Какая команда в HTTP запрещает эксплореру открыть множественные соединения?
2. Что делать другим клиентам данного "сервера" HTTP, когда это одно соединение уже открыто кем-то?

Последний ответ на это от вас был:
Ищите ошибку в своей реализации сервера.
:)
 

rst

Member
Сколько тут ахинеи настрочил наш "гура всея ESP". 😄 Но так и не ответил на заданный выше вопрос: "почему по вашей версии TIME_WAIT должен приводить к "загрузке страницы с десятком файлов за час""?
Ответ на конкретный вопрос будет? Или и дальше будет такой же невразумительный поток бессознания?
 
Сверху Снизу