2012-04-19 3 views
7

내 C# .NET 응용 프로그램이 현재 수행하는 (무엇보다도) 다음 소켓 응용 프로그램이 종료 후 닫히지 않습니다

  1. 가 특정 포트에 소켓을 여는 스레드를 생성

    및 지시를 기다린다.
  2. 메시지가 들어 오면 소켓 스레드는 메시지를 읽고 이벤트를 발생시킵니다.
  3. 이벤트 처리기는 메시지를 구문 분석하는 데 필요한 함수를 호출하고 응용 프로그램 시작과 같은 필요한 작업을 수행합니다.
  4. 지정된 외부 "응용 프로그램"이 비동기 적으로 시작됩니다.

응용 프로그램을 다시 시작했지만 외부 응용 프로그램이 닫히지 않으면 소켓이 닫히지 않는 것 같습니다. 그런 다음 해당 포트에서 다시 통신을 시작하려고하면 오류가 발생합니다. 그러나 외부 응용 프로그램을 닫으면 해당 포트에서 소켓을 열 수 있습니다.

내 프로그램이 제대로 종료되지 않는 것 같습니다. 종료 할 때 소켓을 종료해야하지만 외부 프로세스가 실행 중일 때 소켓이 닫히지 않아야합니다.

아이디어가 있으십니까? 당신은 다른 응용 프로그램에서 모든 소켓을 사용 않음 사용하여 키워드

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

으로이 문제를 해결 할 수있을 것

+0

소켓을 폐기 하시겠습니까? –

+0

외부 프로세스는 어떻게 실행하고 있습니까? 몇 가지 코드를 게시하십시오. – zmbq

+0

@ M.Babcock 예 소켓을 닫고 UI가 닫힐 때 코드가 실행되고 있는지 확인했습니다. 나는 TcpClient와 TcpListener를 사용하고있다. 클라이언트가 "닫혀"있고 청취자가 "중지됨"입니다. 그러나 이것은 포트를 비우지 않는 것처럼 보입니다. – JSideris

답변

13

이것은 외부 프로세스를 시작하는 방법을 보았 기 때문에 찌르기입니다. 당신은 프로세스 개체를 만드는 경우, 내 생각 엔 당신이 설정하지 않는 것입니다 :

인 UseShellExecute를 false로 설정하면
ProcessStartInfo.UseShellExecute = true; 

, 자식 프로세스는 열려있는 소켓이 부모 프로세스에서 핸들을 상속합니다. 부모 응용 프로그램이 닫힌 경우에도 소켓을 열어 둘 수 있습니다.

+0

바로 돈입니다. UseShellExecute가 false로 설정되어 입력 스트림을 리디렉션하거나 처리 할 수있었습니다. 리디렉션을 없애고 UseShellExecute를 true로 설정하면 포트가 해제됩니다. 감사! – JSideris

+0

기꺼이 도와 드리겠습니다. 한 달 전에이 문제와 관련했습니다. 객체가 적절히 폐기 된 경우에도 소켓 오류가 발생한 후에 소켓 오류가 발생했습니다. 운좋게도 여기에있는 사람들 중 한 명이 MSDN에 묻혀있는 것을 발견했습니다. – Josh

+0

[http://stackoverflow.com/a/24677139/4123833](http://stackoverflow.com/a/24677139/4123833)와 동일하게 다른 두 가지 솔루션/옵션이 포함되어 있습니다. – aspark

0

?

+0

다른 응용 프로그램은 소켓을 사용하지 않습니다. 내 시스템에서 무작위로 응용 프로그램을 테스트하고 있습니다 ... 예를 들어 firefox. – JSideris

+0

그냥 외부 응용 프로그램을 열지 않으면 문제가 발생하지 않는지 확인하십시오. – Anders

+0

예 외부 앱이 실행되지 않으면 소켓이 해제됩니다. – JSideris

1

내가 발견 한 것부터 here 내 의혹이 부모로부터 핸들을 상속하는 새로운 프로세스의 케이스 인 것으로 확인되어 문제를 일으킬 수 있습니다.

핸들을 상속받지 않도록 플래그가 설정된 Windows CreateProcess API를 직접 호출하기 위해 해당 링크의 코드를 복사/붙여 넣기 할 수 있습니다.

또 다른 아이디어는 명령 줄 정보를 받아서 시작하고 종료하는 중간 시작 프로그램을 작성하는 것입니다. 이 여분의 간접적 인 지시는 당신이 거의 노력하지 않아도되는 곳에 당신을 데려다 줄 것입니다.

+0

매우 간단한 노력으로'cmd'가 그런 _intermediate 런처 _에 잘 어울리는 것 같습니다. –

0

가장 먼저 응용 프로그램이 닫힐 때 소켓 상태를 살펴 보는 것입니다. 소켓은 TIME_WAIT 상태 일 수 있습니다. 즉, 다른 메시지가 수신되지 않도록 잠시 기다릴 것입니다. 여기에 대한 내용은 다음에서 읽을 수 있습니다 : http://www.isi.edu/touch/pubs/infocomm99/infocomm99-web/ TIME_WAIT 상태는 연결 종료 절차를 시작한 소켓에 따라 소켓에서 생성됩니다. 따라서 어떤 이유로 소켓이 서버 사이트에서 서버 작업 (서버의 포트에있는)에서 닫기 작업을 수행하면 소켓은 TIME_WAIT 상태로 바뀝니다. 따라서 소켓에서 서버 응용 프로그램을 다시 시작하면 TIME_WAIT에 있습니다. 새로운 소켓은 청취 포트에 바인드하는데 실패합니다. 당신이 만난 문제입니다.

관련 문제