|
Модераторы: xvr |
|
Zerstroer |
|
||||
Опытный Профиль Группа: Участник Сообщений: 285 Регистрация: 8.8.2007 Где: Алма-Ата Репутация: нет Всего: 3 |
Здравствуйте.
Знаю, что вопрос относительно тривиальный, но обращаюсь за помощью и что бы разобраться в ситуации. Пишу под Linux. Работаю с сокетами. Использую "чистый" C. Создаю сокет:
Благополучно соединяюсь с ним, работаю, по завершению работы или при возникновении ошибок делаю его close(sock_descr). Далее, в зависимости от ситуации, мне нужно повторно использовать sock_descr. Либо повторно им воспользоваться, если я не делал ранее его close, либо заново сделать connect и пользоваться им. Вопрос заключается в следующем: как в определенном месте однозначно надежно (и по возможности просто) выяснить, что этот дескриптор сокета был ранее closed? Решение этого вопроса гуглил, но в ходу не совсем очевидные мне методы выяснения статуса сокета. Рекомендуют использовать read/write, но у меня вызывает сомнение использование этого метода. Адекватный ли вариант "мануально" контролировать статус сокета посредством использования рукописной структуры? Пример:
Заранее спасибо. -------------------- In silico |
||||
|
|||||
feodorv |
|
||||||||
Эксперт Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 1 Всего: 45 |
Довольно странный подход. Если сокет был закрыт, то его дескриптор становится свободным, а память под внутренние структуры высвобождена. Как его можно использовать? Никак. К тому же любой последующий open/fopen/socket может занять этот дескриптор, и прощай надежды...
Опять-таки, после закрытия сокета его использовать никоим образом нельзя. Поэтому очень часто пишут так:
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||||
|
|||||||||
Zerstroer |
|
|||
Опытный Профиль Группа: Участник Сообщений: 285 Регистрация: 8.8.2007 Где: Алма-Ата Репутация: нет Всего: 3 |
Перечитал свой первый пост, достаточно запутанно описал ситуацию.
По сути, в случае ошибки, мне нужно делать полное переподключение и я использую один и тот же дескриптор сокета. Как выходить из этой ситуации? Вручную присваивать дескриптору после close значение -1? Как в таком случае открывать этот дескриптор повторно? -------------------- In silico |
|||
|
||||
Alexeis |
|
|||
Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: нет Всего: 459 |
ООП наш лучший друг в слежении за ресурсами. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
feodorv |
|
|||
Эксперт Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 1 Всего: 45 |
В случае какой ошибки? Ошибки бывают слишком разные.
Зачем? В чем причина необходимости для использования того же дескриптора сокета? Почему бы просто не закрыть сокет, а потом его по-новой открыть в случае переподключения? У Вас им удерживается свой IP:port? -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Zerstroer |
|
|||
Опытный Профиль Группа: Участник Сообщений: 285 Регистрация: 8.8.2007 Где: Алма-Ата Репутация: нет Всего: 3 |
Alexeis, ООП использовать не могу - "чистый" Си.
feodorv, по поводу ошибок. Имеются ввиду ошибки при подключении или при обмене данными (хост недоступен, порт занят, сервер не возвращает данные). В каждом из этих случаев мне необходимо осуществить несколько попыток повторного подключения. Я принял во внимание ваши советы, пересмотрел код. Вопросы стали еще проще и еще банальнее: 1. Фактически close не изменяет значение дескриптора сокета, а лишь закрывает его. Верно? Т.е. после close я могу присвоить переменной в которой ранее хранился действующий дескриптор сокета отрицательное значение для индикации того, что сокет закрыт? 2. Дескриптор действующего сокета не может быть отрицательным. Может ли дескриптор сокета быть равным 0? -------------------- In silico |
|||
|
||||
feodorv |
|
|||
Эксперт Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 1 Всего: 45 |
По сути верно, по форме я бы иначе сказал. Дело в том, что переменная сокета хранит дескриптор сокета, и при close данный дескриптор высвобождается и более ничему не соответствует (ни файлу, ни сокету), хотя переменная сокета продолжает хранить значение этого уже освобождённого дескриптора. Чтобы она этого не делала, и для индикации закрытости сокета, стОит присвоить переменной сокета отрицательное значение (обычно используют -1). Не может. Более того, отрицательное значение, возвращаемое вызовом socket(), сигнализирует об ошибке. Вообще, значения дескрипторов 0, 1 и 2 отведены под stdin, stdout и stderr. Если их последовательно закрыть, а затем сделать вызов socket(), то вполне возможно получить нулевое значение дескриптора сокета. По крайней мере, так было в Юниксах лет 10 назад, к сожалению, меня с тех пор от них оторвали, я не в курсе последних тенденций в этом направлении. Но учитывая значительный консерватизм в разработке Юниксов, не думаю, что здесь что-то изменилось. Можно, кстати, поставить эксперимент. Но в любом случае по стандарту нужно быть готовым к тому, что значение дескриптора сокета может быть нулём))) -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Zerstroer |
|
|||
Опытный Профиль Группа: Участник Сообщений: 285 Регистрация: 8.8.2007 Где: Алма-Ата Репутация: нет Всего: 3 |
feodorv, большое спасибо! Вы все объяснили до очевидного понятно.
Ответы на все сформулированные вопросы я получил. Тему закрою если не возникнет дополнительных вопросов при исправлении взаимодействия с сокетами в коде. -------------------- In silico |
|||
|
||||
Zerstroer |
|
|||
Опытный Профиль Группа: Участник Сообщений: 285 Регистрация: 8.8.2007 Где: Алма-Ата Репутация: нет Всего: 3 |
Помечаю вопрос как решенный.
Воспользовался советами feodorv. -------------------- In silico |
|||
|
||||
svlary |
|
|||
Бывалый Профиль Группа: Участник Сообщений: 207 Регистрация: 8.9.2009 Репутация: 4 Всего: 4 |
Там есть одна заморочка, с которой я столкнулся на практике... Описываю ситуацию
Было у меня это очень давно и потому "помню туманно" Но там как-то надо использовать опцию сокета SO_REUSEBLE_ADDR. Как-то так она пишется... |
|||
|
||||
Alexeis |
|
|||
Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: нет Всего: 459 |
ОС закрывает соединение при возникновении любой неисправимой ошибки. Но это не имеет отношения к теме обсуждения. Автор спрашивал как проверить закрыт или открыт сокет, а не соединение. Сокет может быть открытым как при открытом так и при закрытом соединениях. Есть еще вариант проверки при помощи функции recv . После ожидания таймаута открытый сокет с открытым соединением вернет EAGAIN или EWOULDBLOCK. Закрытый сокет или в состоянии ошибки вернет код ошибки моментально. Но этот способ страдает таймаутом, так что не эффективен. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Правила форума "С/С++: Программирование под Unix/Linux" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |