Socket: Как удостовериться что связь в норме?
А во втором - Акцепт возвратит управление сразу сказав есть клиент или нет.
Точнее, ничего не сказав: об этом узнает автоматически callback. Правильно?
После того, как клиент "попался", Вы бросаете слушать, по-видимому, пока клиент не разорвет связь.
Вариант, который должен сработать: после установления соединения с клиентом продолжать слушать дальше. В колбэке проверять, тот ли это самый клиент, с которым мы думаем, что как раз сейчас "разговариваем", и если да - рвать "старую" связь и разговаривать по "новой". Если это другой какой-то клиент - давать отлуп.
функция с callback называется BeginAccept вроде. Я ей не пользуюсь, т.к. библиотеки(не от Майкрософт) что работают на контроллерах предоставляют необходимый минимум, и эта функция в него не вошла. А функция Accept в неблокируемом режиме возвращает сразу: либо Socket клиента, либо бросает исключение типа - клиента нет. Поэтому надо периодически ее вызывать, пока она не возвратит Сокет.
А вот дальше юзер, который пишет программу для контроллера, уже сам решает кто кому (клиен и/или сервер) чего посылает.
Я просто думал что можно в реализации функционального блока встроить проверку обрыва связи, даже если обмена данными нет - но видимо невозможно. Ну и ладно, пусть юзеры это сами проверяют.
Еще вариант: выбираем блокируемый сокет на сервере. Выдаем в бесконечном цикле акцепт() и висим, пока кто-нибудь не сконнектится. Если это - наш первый клиент, создаем трэд и передаем туда сокет, и там происходит "логика". По циклу возвращаемся к акцепт() и снова зависаем. Рабочему соединению это не мешает. Еще кто-то сконнектился - смотрим, активен ли трэд, если нет, или если там висит тот же клиент, который только что сконнектился - принять соединение и заново инициализировать трэд (или грохнуть и создать новый, или воспользоваться трэдпулом, если он имеется в Вашем кастрированном рантайме). Если трэд активен, и новый клиент - не тот же, отфутболиваем новичка.
выбираем блокируемый сокет на сервере. Выдаем в бесконечном цикле акцепт()
в программировании контроллеров на языках что я указал есть своя специфика: там нельзя зависать (или делать долгие циклы). Задача получает периодически управление (период задается в настойках) и должна как можно быстрее сделать свое дело и выйти. Если делать - много, то должна сделать чуть чуть, выйти и доделать в следующий раз.
Поэтому использование сокета в блокируем режиме - неприемлимо. (ну разве что создавать отдельный поток с таким сокетом, но не охота плодить потоки)
А в Вашем обрезанном рантайме есть thread pool? Если есть, то Вы его вряд ли на полную используете (в стандартном - 20 потоков). Так что возможно, ничего не придется плодить.
Но в общем, конечно, не зная конкретных обстоятельств, можно только спекулировать и подсказывать просто варианты, а уж Вам вибирать и отвечать за выбор. Если в дизайне заложить неудобоство, будет головная больш всем и навсегда.
НП.
Заметил особенность Socket.Receive (в не блокируемом режиме):
- если данных нет (никто данных не отправлял, но связь в норме), то функция бросает исключение
- если связь оборванна, то функция не бросает исключения, а возвращает значение 0 (количество полученных байтов)
Вот думаю : всегда ли и везде ли будет такое поведение?