Повідомлення створено: 21. 01. 2015 [13:25]
|
vi7.vo7
Виктор Шехов
Автор теми
Зареєстрован(а) с: 21.01.2015
Повідомлення: 2
|
Добрый день,
Пишу свою реализацию пользовательского протокола для устройства, работающего по TCP, на котором после установления соединения, необходимо авторизоваться и после этого, до закрытия соединения можно отсылать и принимать данные. Мало того, если через канал не передаются данные в течение определенного промежутка времени – канал связи закрывается. Кроме того, устройство немного «злое», и если авторизуешься неверно, оно не присылает в ответ ничего...
И у меня возникла проблема: как мне отследить состояние сокета в выходной программе пользовательского протокола - есть связь или нет, и если связь есть, то когда она была установлена (или что-то подобное, чтобы я смог отследить, что канал связи закрывался и мне нужно заново авторизоваться)? Пожалуйста, подскажите, как это лучше и правильнее реализовать?
|
Повідомлення створено: 22. 01. 2015 [11:14]
|
roman
Roman Savochenko
Moderator Contributor Developer
Зареєстрован(а) с: 12.12.2007
Повідомлення: 3750
|
"vi7.vo7" wrote:
Пишу свою реализацию пользовательского протокола для устройства, работающего по TCP, на котором после установления соединения, необходимо авторизоваться и после этого, до закрытия соединения можно отсылать и принимать данные. Мало того, если через канал не передаются данные в течение определенного промежутка времени – канал связи закрывается. Кроме того, устройство немного «злое», и если авторизуешься неверно, оно не присылает в ответ ничего...
И у меня возникла проблема: как мне отследить состояние сокета в выходной программе пользовательского протокола - есть связь или нет, и если связь есть, то когда она была установлена (или что-то подобное, чтобы я смог отследить, что канал связи закрывался и мне нужно заново авторизоваться)? Пожалуйста, подскажите, как это лучше и правильнее реализовать?
Статически проверить состояние сокета из клиентского API практически невозможно и тому есть причина, связанная с отсутствием контрольных запросов проверки состояния сокета на уровне транспорта протокола TCP. Например, на стороне сервера OpenSCADA, замечается накопление подключений и достижение в конечном итоге их количества лимиту, если время KeepAlive не установлено. А связано это как-раз с тем, что если клиент пропадает без закрытия (когда клиент уведомляет сервер), а, например, в случае аварийного отключения или зависания клиента, то и сервер никогда не узнаёт о том, что сокет-подключение фактически закрылось. Возможно это как-то и настраивается, но данное поведение типично.
В любом случае узнать о том, что установленного канала связи уже нет, можно только отправкой нового запроса, в результате чего транспорт OpenSCADA попробует переподключиться и если не получится вернёт ошибку.
Думаю в вашем случае нужно просто:
1. отправлять запрос аутентификации;
2. при успешном результате аутентификации слать запросы данных пока не перестанет отвечать;
3. при отсутствии ответа как на запрос аутентификации, так и данных возвращаться к пункту 1 через разгрузочный таймаут.
Learn, learn and learn better than work, work and work.
|
Повідомлення створено: 22. 01. 2015 [23:18]
|
vi7.vo7
Виктор Шехов
Автор теми
Зареєстрован(а) с: 21.01.2015
Повідомлення: 2
|
Спасибо за ответ.
Примерно, по вашему алгоритму удалось сделать, даже проще… Суть механизма в том, что я сразу пытаюсь выполнить команду опроса статуса и если меня выбивает на авторизацию, значит заново авторизируемся, иначе работаем как нужно.
|
Повідомлення створено: 24. 01. 2015 [14:12]
|
roman
Roman Savochenko
Moderator Contributor Developer
Зареєстрован(а) с: 12.12.2007
Повідомлення: 3750
|
"vi7.vo7" wrote:
Примерно, по вашему алгоритму удалось сделать, даже проще… Суть механизма в том, что я сразу пытаюсь выполнить команду опроса статуса и если меня выбивает на авторизацию, значит заново авторизируемся, иначе работаем как нужно.
Обратите внимание на то, что вычитывать ответ нужно до критерия окончания посылки, согласно протоколу или по таймауту, примеры тут: http://wiki.oscada.org/Doc/OpisanieProgrammy#h920-14
Иначе ответ, для больших посылок, может быть не полным, а при следующем чтении (без запроса) можно ошибочно получить остаток.
Также почитайте про особенности циклического программирования, что-бы не понизить отзывчивость интерфейса помещением указанных запросов в процедуры интерфейса визуализации: http://wiki.oscada.org/Doc/QuickStart#h988-26
Learn, learn and learn better than work, work and work.
|