2014-09-15 5 views
0

У меня проблема с C++-службой, которая использует порт 30015. Он работает нормально, но когда-то он не запускается, поскольку порт 30015 занят и сбой связи с ошибкой WSAEADDRINUSE.Порт остается занятым, даже если приложение выключено.

Я побежал NETSTAT команду, чтобы узнать состояние порта

netstat -aon | findstr 30015 

Выход:

TCP 0.0.0.0:30015 0.0.0.0 сЛушАНИЕ 6740

Я проверил PID 6740 в диспетчере задач, этот PID не принимается процессом.

После поиска в сети я использовал TCPVIEW для просмотра состояния порта. TCPView показывает порт в режиме прослушивания, а имя процесса - «не существует».

Приложение в основном сжимает, распаковывает файл с помощью 7za. Приложение прослушивает порт 30015 для запроса и создает дочерний процесс и передает командную строку для запуска команды 7za для сжатия и распаковки файла.

Здесь дочерний процесс не использует сокет. Сервер работает в основном потоке и прослушивает порт 30015. Эта проблема возникает после перезагрузки сервера.

Здесь дочерний процесс не использует сокет как таковой. Мне нужно сделать bInheritHandle = FALSE?

ответ

0

Уверены ли вы? Все это звучит очень смутно. Невозможно, чтобы netstat отображал сокет в состоянии LISTEN, но для этого не было никакого процесса - особенно если он показывает pid! Вы сбиты с толку, потому что процесс просто вышел к моменту вашего просмотра в диспетчере задач. Все TCP-соединения в netstat связаны с запущенным процессом (за исключением необычных случаев, таких как сокеты TIME-WAIT). Итак, узнайте, какой процесс открыт.

Во-вторых, я думаю, вы пытаетесь сказать, что использование bInheritHandles=TRUE в качестве аргумента для CreateProcess может привести к утечкам ручек. Только у вас есть код - почему бы просто не взглянуть на ручки у вашего ребенка и посмотреть, есть ли у вас утечка? Можно использовать только bInheritHandles=TRUE с большой дисциплиной, в руках начинающих программистов это приведет только к ошибкам. Создайте именованный канал с подходящим дескриптором безопасности, передайте имя в командной строке дочернему устройству и подключитесь обратно, вместо того, чтобы использовать наследование дескриптора, которое слишком грубо.

И, наконец, чтобы убедиться, что вы знаете, чтобы связать прослушивающие сокеты с SO_REUSEADDR, чтобы предотвратить конфликт с активными сокетами, используя тот же порт? (SO_REUSEADDR по-прежнему не допускает создания двух пассивных сокетов с одной и той же комбинацией адресов/портов, хотя в Windows это немного сломается.)

+0

Да, это true.I перекрестно проверено с использованием утилиты TCPVIEW.Там он показывает имя процесса как несуществование, и он занимал порт. Я хотел знать, что делать, если я делаю bInheritHandles = FALSE. Будет ли это ограничение доступа дочернего процесса к сокету. –

+0

Я создаю дочерний процесс для выполнения 7za (сжимать/распаковывать). Процесс command.child не использует сокет или порт. Даже если дочерний процесс не использует сокет/порт как таковой, выполните bInheritHandles = TRUE заставляет дочерний процесс занять сокет/порт –

0

Да, это может произойти в Windows. Если вы создали дочерний процесс, который наследует дескрипторы родительского процесса, то он включает в себя сокеты TCP-сервера в состоянии LISTEN, которые всегда будут перечислены как принадлежащие родительскому PID даже после того, как этот PID скончался.

Эти сокеты исчезнут, когда все дочерние процессы, которые вы породили, вышли, в результате чего счетчик ссылок на их ручках достигнет нуля.

С точки зрения безопасности вы не должны использовать межоперационное управление обработкой, особенно при запуске приложения третьей части, если у вас нет веских оснований для использования этой функции.

+0

Вы имеете в виду, что мне нужно передать bInheritHandles = FALSE в CreateProcess? –

+0

Справа. 7Z не нужно наследовать какие-либо из ваших открытых дескрипторов, если он просто получает все необходимое в командной строке, например. имена файлов ввода/вывода и флаги параметров сжатия/декомпрессии. –