Opened 3 months ago

Closed 3 months ago

Last modified 3 months ago

#418 closed улучшение (invalid)

Странности в работе канального окончания R485

Reported by: san Owned by: alx
Priority: низкий Milestone: 1 очередь
Component: any Keywords:
Cc:

Description (last modified by san)

Я заметил некоторое неинтуитивное для меня(как пользователя) поведение в работе модулей и предлагаю это поведение сделать более логичным (ожидаемым).

  1. Я провёл эксперимент

1.1 В канале 256 я создал сервер
1.2 В канале 255 создал клиент(соединив его по TCP с сервером в канале 255)
1.3 Оба окончания отобразили состояние Connected
1.4 Затем в канале 255 я изменил режим Клиент на режим Сервер выбрав порт, который уже занят сервером в канале 256. Я ожидал, что соединение разорвётся, сервер в канале 256 перейдёт в режим Listen, а сервер в канале 255 не сможет занять уже занятый порт и перейдёт в Error.
1.5 Однако получилось наоборот сервер в канале 255 оказался в состоянии Listen, а 256 - Error.

  1. Затем я провёл второй эксперимент

2.1 Настроил в одном из окончаний R485 сервер на порту 12912
2.2 Подключился к нему внешним клиентом по TCP
2.3 Затем в другом окончании R485 настроил сервер на том же порту 12912. Я ожидал, что это окончание перейдёт в состояние Error, т.к. порт уже занят другим окончанием.
2.4 Однако окончание перешло в состояние Listen, и я даже смог подключиться к нему клиентом и данные успешно передавались в обоих соединениях. Итого я получил два сервера нормально работающих на одном порту 12912. Вроде бы это неплохо) но после перезапуска платы, такая конфигурация не будет работать, т.к. только одно окончание сможет занять порт.

Всё сказанное наверное распространяется и на R422 и R232.

Attachments (1)

11.png (21.8 KB ) - added by san 3 months ago.

Download all attachments as: .zip

Change History (5)

by san, 3 months ago

Attachment: 11.png added

comment:1 by alx, 3 months ago

Правильно ли я понял, что "сделать поведение более логичным" - это и есть предложение, ради которого был создан этот тикет?

comment:2 by san, 3 months ago

Description: modified (diff)

Ага, правильно.

p.s. Добавил в текст тикета упоминание R422 и R232, для поиска

comment:3 by alx, 3 months ago

Resolution: invalid
Status: newclosed

Вынужден закрыть с резолюцией invalid, так как тикет не содержит никакого конкретного предложения. Прошу прощения за прямоту, но предложить "сделать более логично", не уточнив, как именно - это все равно что предложить "сделать лучше". А что, всегда ведь можно сделать лучше, так почему бы не создать тикет с таким предложением? :)

Если бы я (разработчик) знал, как сделать логичнее, я бы, конечно, сделал это и без данного тикета. :) Конечно же ничего нелогичного я в текущей реализации не нахожу. Зато я нахожу нелогичное в описанных ожиданиях.

В первом из описанных экспериментов мы имеем (после выполнения п. 1.4) два одинаково настроенных канальных окончания, конкурирующих за один ресурс (порт). И при этом почему-то ожидалось, что конкуренцию выиграет одно из них. Это нелогично, так как не вижу для такого ожидания никаких оснований.

В общем случае здесь имеют место гонки (race condition) - какое канальное окончание первым запросит порт, то его и получит, и перейдет в состояние Listening. Нет логических оснований предполагать, что первым всегда будет окончание 256.

В данном же конкретном эксперименте канальные окончания не в равных условиях. Конфигурация изменена только канальному окончанию 255. Что происходит после этого? Канальное окончание 255 закрывает соединение и начинает слушать порт. Следствием закрытия соединения окончанием 255 является отправка пакета FIN удаленной стороне. Получив FIN, окончание 256 также закрывает текущее соединение и пытается начать слушать тот же самый порт. То есть выполняет те же самые действия. Но так как действия окончания 256 являются следствием закрытия соединения окончанием 255, то логично ожидать, что и выполнятся они позже:

Дополнительно могу сказать, что вся работа окончаний выполняется асинхронно в одном потоке, поэтому в данном случае даже никаких гонок нет. :)

Кстати, в описании эксперимента в п. 1.4 ошибка - на момент выполнения пункта порт не занят, так как окончание 256 не в состоянии listening, а в состоянии connected. На момент выполнения п. 1.4 порт никто не слушает, он свободен.

По второму из описанных экспериментов. В п. 2.3 та же самая ошибка. Порт не занят другим окончанием, так как другое окончание не находится в состоянии listening: в предыдущем п. 2.2 написано, что к серверу подключился клиент. А раз так, то сервер перешел из состояния listening в состояние connected! А раз так, то и ожидание, основанное на ошибочном факте, тоже ошибочно.

По поводу интуитивности или неинтуитивности судить не берусь, так как интуиция у каждого своя - у нее нет строгих правил (как у логики)...

Last edited 3 months ago by alx (previous) (diff)

comment:4 by san, 3 months ago

Порт не занят, так как окончание 256 не в состоянии listening, а в состоянии connected

Понятно. Но вот это не показалось очевидным и мне и Артёму(который первый обнаружил эту "странность" ) и Владу, который помогал проводить эксперимент. Мы все предполагали, что раз сервер занял порт, то он и останется занятым в состояние connected.

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

Note: See TracTickets for help on using tickets.