Сокет не закрывается после выхода приложения, если запущенный процесс открыт

мое приложение C# .net в настоящее время делает следующее (среди прочего):

  1. создает поток, который открывает сокет на определенном порту и ждет команды.
  2. приходит сообщение, поток сокета считывает сообщение и вызывает событие.
  3. обработчик событий вызывает необходимые функции для разбора сообщений и выполняет необходимые действия, например, запуск приложения.
  4. указанное внешнее " приложение" запускает, асинхронно.

когда мое приложение перезапускается, но внешнее приложение не закрывается, сокет, похоже, никогда не закрывается. Затем, когда я пытаюсь снова запустить связь на этом порту, я получаю ошибку. Однако, как только я закрываю внешнее приложение, я могу открыть сокет на этом порту.

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

какие идеи?

4 ответов


Это просто удар, потому что я видел, как вы начинаете внешний процесс. Если вы создаете объект процесса, я предполагаю, что вы не устанавливаете:

ProcessStartInfo.UseShellExecute = true;

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


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

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

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


вы можете решить эту проблему с помощью ключевого слова using

using (Socket socket = new Socket()) {
//The code
}

использует ли другое приложение сокет вообще?


первое, что нужно посмотреть на состояние сокета, когда приложение закрыто. Сокет может находиться в состоянии TIME_WAIT, что означает, что он будет ждать некоторое время, чтобы убедиться, что никакие другие сообщения не будут получены. Вы можете прочитать об этом здесь: http://www.isi.edu/touch/pubs/infocomm99/infocomm99-web/ Теперь состояние TIME_WAIT будет сгенерировано на сокете в соответствии с тем, кто из них инициировал процедуру завершения соединения. Так что если для некоторых причина, по которой ваш сокет выполняет действие закрытия на сайте сервера, а затем на сайте сервера ( в порту сервера ) сокет изменит состояние на TIME_WAIT, поэтому, если вы перезагрузите серверное приложение во время сокета в TIME_WAIT, новый сокет не сможет привязаться к порту прослушивания, я думаю, что это проблема, с которой вы столкнулись.