2009-06-17 5 views
4

В последнем семестре я занял компьютерную сеть и проделал некоторое программирование на C в Linux (используя gcc) для моих проектов. Одна очень утомительная вещь, с которой я столкнулся, заключалась в том, что если моя программа разбилась или заглохла (мне тогда пришлось бы нажать Ctrl + C, чтобы ее убить), сетевой порт все равно оставался открытым на минуту или около того. Поэтому, если я захочу снова запустить программу снова, мне придется сначала перейти в файл заголовка, изменить порт, переделать программу и затем запустить ее. Очевидно, это очень утомительно очень быстро.Как предотвратить порты сети, оставшиеся открытыми при сбое программы

Есть ли способ настроить его, когда порт сразу же освобождается, как только процесс будет убит? Либо через некоторые настройки в Linux, либо в make-файле для моей программы, или даже программно в C?

Редактировать: Я имею в виду при написании сервера и выборе конкретного порта для размещения программы.

+1

Вы можете обойти эту проблему путем выбора случайного порта, и печать его на исполнение. – Tordek

+0

@Tordek Хорошая точка, но я просто собираюсь отметить здесь для потомков, что если вы это сделаете, вам нужно выбрать безопасный диапазон, чтобы вы не наткнулись на какие-либо стандартные порты. – JoeCool

+0

Ну, да ... беззаботно избегайте может заставить вас шагнуть на собаку ... – Tordek

ответ

11

Установите опцию SO_REUSEADDR на розетку.

int yes = 1; 
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); 

От Beej's Guide to Network Programming.

+0

Это хорошая идея. Другой альтернативой является код вашей программы для приема номера порта в качестве входного сигнала, чтобы избежать перекомпиляции. Чтобы фактически освободить порт, как вы хотите, вам нужно написать обработчик Ctrl-C и закодировать его. – nik

+0

(Не связанный) Что думал кто-то, чтобы сделать этот четвертый аргумент указателем на int вместо int? – Kai

+0

Это правда, вышеприведенное решение фактически не выпускает сокет, но оно позволяет повторно привязываться к следующему исполнению. – Cogsy

1

Я предполагаю, что программа, которую вы пишете, является сервером, поэтому вам нужно использовать известный порт. Если это так, вы должны использовать опцию SO_REUSE_ADDR в сокете, как указано Cogsy.

Если, с другой стороны, вы пишете клиент sw, то вам следует избегать выбора конкретного порта, позволяя системе передать вам случайный.

+0

Да, я имею в виду при написании сервера, спасибо. – JoeCool

2

Держу пари, что это около двух минут :) Как отметил @Cogsy, опция сокета SO_REUSEADDR - ваш друг. Сделайся знакомы с TCP состояниями, это TIME_WAIT состояние, которое вызывает у вас проблемы:

 
 
+1

Все, я бы гораздо счастливее с копией удивительной диаграммы ASCII со страницы 23 RFC 793. – ephemient

+0

О, да! Я полностью забыл о прекрасном искусстве ASCII-картин :) –