| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Сети > Sockets: address already in use |
| Автор: Rickert 16.3.2007, 07:32 |
| Был открыт сокет на определённом порту, программа работала - работала, потом случилось так, что программе понадобилось открыть новое соединение на этом порту, но предыдущее - закрыть не представляется возможным (данные о дескрипторе сокета отсутствуют). При попытке забиндиться программа вернёт "address already in use" есесно. Вопрос: как мне закрыть старую сессию знаю порт? Машина локальная. |
| Автор: ptr 16.3.2007, 18:49 |
Это как? Про это поподробнее. |
| Автор: SparF 16.3.2007, 20:24 |
| желательно с кодом |
| Автор: Dude03 17.3.2007, 12:39 |
| Могу предложить грязненький хак: можно перебрать все идентификаторы сокетов и для каждого получить порт. Если порт - тот самый - действуем...=) |
| Автор: Rickert 17.3.2007, 13:41 |
Был дескриптор, потом, например, программу перезапустили, незакрыв сокет - он остался в системе. Через некоторое время ОСь конечно сама его закроет, но меня интересует возможность закрыть самому. |
| Автор: Dude03 17.3.2007, 15:59 |
| В винде такой проблемы нету=). Указывай в следующий раз свою операционную систему. |
| Автор: Rickert 17.3.2007, 17:27 |
| dude Альт Линукс |
| Автор: Rickert 18.3.2007, 07:54 | ||
В деструкторе есесно всё прописано, но я имею ввиду аварийную принудительную остановку. Какую его часть именно? создание сокета? Попытка connect()'а? |
| Автор: SparF 18.3.2007, 08:34 | ||||
аварийная остановка - это именно аварийная остановка, ситуация экстренная. После нее ядру приходится разгребать все то, что когда-то было процессом. Но и тут есть свои приколы. Так, к примеру
всего навсего посылает процессу сигнал SIGTERM, а на него можно повесить обработчик, который уже будет закрывать соединение и т.д. и т.п., иными словами - грамотно освобождать ресурсы. Если же прога ну совсем висит, то решение одно:
этот посылает уже SIGKILL, его уже не перехватишь, вот это действительно экстренное завершение. Но такое бывает, только если прога написана некорректно. Решение одно - писать надо так, чтобы не зависало) |
| Автор: Rickert 18.3.2007, 10:38 |
| Да нет, ты меня не понял. Во время выполнения программы нажимаю ctrl + z и всё. И вообще - это не имеет значения вопрос-то: как закрыть уже открытый сокет, не имея его дескриптора, но зная порт? |
| Автор: SparF 18.3.2007, 13:07 | ||||||
Так это не должно завершать процесс. Это просто останавливает его, и убирает в фон! (В случае если используется bash) man bash
А это значит, что процесс остается запущенным (просто остановленным) и занимает сокет на законных основаниях.
посмотреть какой процесс открыл соединение на данном порту и грохнуть процесс.
выдаст даст PID, который надо убить) |
| Автор: Rickert 19.3.2007, 04:46 |
| Нет, ты не прав. Даже грохнув процесс - некоторые сокеты всё равно не могут открыться. "Already in use" и всё. |
| Автор: ptr 21.3.2007, 18:17 | ||
| Так господа давайте по-порядку. Если сокет используется несколькими процессами, то он закроется, только когда его закроет последний процесс. Поэтому, чтобы освободить сокет нужно убить процессы, использующие этот сокет.
Читаем и просвещаемся про TCP и сокеты, а также про SO_REUSEADDR (setsockopt). Например, в Стивенсе и Снейдере. |
| Автор: SparF 21.3.2007, 20:18 | ||||
| ptr, за SO_REUSEADDR спасибо - не знал. А в это время в манах все русским по белому написано)) man 7 ip
man 7 socket
|
| Автор: ptr 22.3.2007, 10:43 |
| И что? |