Очень умная розетка

sadman41
Offline
Зарегистрирован: 19.10.2016

Если клиент открыл соединение со слушающим W5100, но ничего не заслал, то EthernetServer::available() не будет возвращать хэндл на сокет в состоянии established. Удаленная сторона и WireShark демонстрируют, что коннект установлен, а вот драйвер его коду на Wiring - не показывает. Закрыть его из скетча по таймауту штатным способом, соответственно, возможности нет.

Т.е. открываем четыре коннекта на модуль и блокируем работу устройства. С одной стороны - построенный таким образом код снижает оверхед драйвера и прикрывает газеткой не самый лучший алгоритм обхода активных сокетов, с другой - делает фееричным процесс отладки шести строчек кода с обработкой TCP-сессии . 

В Ethernet2.h (W5500) данный "дефект" так же присутствует.

Вобщем, к незамысловатому скетчу еще три часа попыток осознать причину геморроя... И необходимость внесения в драйвер изменений. Что вообще неизвестно сколько времени займет с учетом времени на попытки понять логику писавшего библиотеку корейца, тестирования правленного кода и пр и др.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

Если клиент открыл соединение со слушающим W5100, но ничего не заслал, то EthernetServer::available() не будет возвращать хэндл на сокет в состоянии established. Удаленная сторона и WireShark демонстрируют, что коннект установлен, а вот драйвер его коду на Wiring - не показывает. Закрыть его из скетча по таймауту штатным способом, соответственно, возможности нет.

Т.е. открываем четыре коннекта на модуль и блокируем работу устройства. С одной стороны - построенный таким образом код снижает оверхед драйвера и прикрывает газеткой не самый лучший алгоритм обхода активных сокетов, с другой - делает фееричным процесс отладки шести строчек кода с обработкой TCP-сессии . 

В Ethernet2.h (W5500) данный "дефект" так же присутствует.

"Поздравляю тебя, Шарик, ..." :) В том смысле - что это старый косяк библиотеки штатной Ethernet - там отвратно ведётся работа с сокетами. Уж сколько лет прошло - и воз и ныне там. Всему виной тот факт, что внутри available всегда возвращается ПЕРВЫЙ занятый сокет, если там просто кто-то висит, но ничего не отсылает - получаем описанное тобой поведение. Вот ссылка: https://habr.com/post/382565/

Короче, дичь там творится, на уровне кода. Сам стек внутри W5100 - норм, проблема в "быдлоотеке". Решается, кстати, гораздо проще, чем по ссылке в статье: надо всего-лишь итератор условия начала цикла сделать static, и постоянно смещаться на 1 при вызове available - таким образом, не будет постоянный просмотр пула сокетов сначала. Ещё лучше, конечно - кольцевой список, с инкрементированием указателя чтения.

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

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Про тот баг я давно знаю, этот "новый".  

EthernetServer::available() унутре проверяет экземпляры EthernetClient::available(), а тот, в свою очередь (какая неожиданность!) - просит у чипа размер занятого фрагмента буфера RX. Нет вошедших данных -> размер нулевой -> активного коннекта нет. Логика!

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

Про тот баг я давно знаю, этот "новый".  

EthernetServer::available() унутре проверяет экземпляры EthernetClient::available(), а тот, в свою очередь (какая неожиданность!) - просит у чипа размер занятого фрагмента буфера RX. Нет вошедших данных -> размер нулевой -> активного коннекта нет. Логика!

О как! Спс, надо запомнить. Там вся эта катавасия - писана так, для отчётности больше , кмк :)  Ибо нефик, паанимаишь - открыть соединение, и ничего туда не писать, распустились тут совсем! :)

sadman41
Offline
Зарегистрирован: 19.10.2016

Round Robin внутри я буду делать, конечно, если придется переписывать, но он не закроет описанную проблему ;)

А тот корявый алгоритм выбора сокета как раз и держится кое-как на том факте, что как только из RX сокета все вычитано, то он пропускается.  Иначе бы все время возвращался один и тот же до его закрытия одной из сторон.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

Round Robin внутри я буду делать, конечно, если придется переписывать, но он не закроет описанную проблему ;)

А тот корявый алгоритм выбора сокета как раз и держится кое-как на том факте, что как только из RX сокета все вычитано, то он пропускается.  Иначе бы все время возвращался один и тот же до его закрытия одной из сторон.

Согласен. Удивляет тот факт, что уже столько лет - как-то же живут с этими вопиющими косяками, и - ничего, воз и ныне там. Емнип, встречал в issues на официальном гитхабе отписки вида "там всё норм и работает как и задумано". Короче, щастья ждать не приходится :(

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

А тот корявый алгоритм выбора сокета как раз и держится кое-как на том факте, что как только из RX сокета все вычитано, то он пропускается.  

Вот именно, что "кое-как": пока будет идти общение по первому сокету - все остальные курят в стороне, норм такое разделение ресурсов в пуле, зашибись :)

Ладно, закрыли тему, там всё печально, сочувствую ;)