2012-08-23 2 views
2

콜백이 필요하기 때문에 비동기 호출을 사용하지 않기로 결정했습니다.이를 활용하여이를 해결할 방법이 있는지 궁금합니다. 유닉스 계열의 비 블로킹 소켓 메소드 : Poll(), Asyn은 Windows 환경을 위해 특별히 제작되었습니다. 비동기없이이 작업을 수행 할 수 있는지 조사하고 있습니다.C# 비 블로킹 Socket.Connect()

가 주목해야! 비 블로킹 = 비동기 따라서 :

나는이 소켓의 & 설문 조사() 메소드를 차단 플래그를 해제하여 다음과 같은 방법 :

try 
    { 
     IPEndPoint hostEp = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); 
     Socket hostSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     hostSock.Blocking = false; 
     hostSock.Connect(hostEp); 

    } 
    catch (Win32Exception se) 
    { 
     if (ex.ErrorCode == 10035) // WSAEWOULDBLOCK is expected, means connect is in progress 
     while (true) 
     { 
      Console.WriteLine("Connecting in progress"); 
      bool connected = hostSock.Poll(1000000, SelectMode.SelectWrite); 
      if (connected) 
      { 
       Console.WriteLine("Connected"); 
       break; 
      } 

     } 
    } 

그러나 SelectMode.SelectWrite는 나를 위해 연결 시도 reinitiates 것 같습니다. 그래서, 무엇이 문제입니까? 어떻게 해결할 수 있을까요? 내가 사용해야 할 것 Select() instead of Poll()?

+1

전용 여러 소켓을 동시에 수신하는 경우 선택하십시오. – Slugart

답변

4

그냥 비동기 메서드 (ConnectAsync())를 사용하면됩니다. 프로그램 논리에 예외를 사용하지 마십시오.

할 수 있습니다 차단하지 않고 기적 Connect() TCP 소켓 :

Manual : 특별히 연결을 호출 거짓 사전에 차단 속성을 설정하지 않는

Connect 메서드가 차단됩니다. TCP와 같은 연결 지향 프로토콜을 사용 중이고 차단을 사용하지 않으면 Connect는 연결하는 데 시간이 필요하기 때문에 SocketException을 발생시킵니다.

SocketException.ErrorCode를 사용하여 특정 오류 코드를 얻을 수 있습니다. 이 코드를 얻은 후에는 MSDN 라이브러리의 Windows 소켓 버전 2 API 오류 코드 설명서에서 오류에 대한 자세한 설명을 참조하십시오.

오류가 WSAEWOULDBLOCK을 (를) 반환 한 경우 원격 호스트 연결은 연결 지향 소켓에 의해 시작되었지만 아직 성공적으로 완료되지 않았습니다. Poll 메서드를 사용하여 소켓 연결이 완료된 시점을 확인하십시오.

하지만 코드가 정확히 무엇을하는지는 잘 작동합니다.

+0

예, 차단을 사용하지 않도록 설정 한 결과를 이해합니다. 그 때문에 연결을 다시 시도 할 수있는 기회가 있습니다. 언급했듯이, 나는 asych 접근법을 사용하지 않기로 결정했다. 대신이 문제에 대한 해결책이 있는가? :) – Roylee

+0

+1 CodeCaster. 왜 비동기 방식을 사용하지 않으시겠습니까?다른 방법이 존재하는지, 비동기 메서드가 존재하는지는 모르겠다. :-), 만약 당신이 비동기식 메소드를 사용하지 않는다면, 소켓 블록에 대한 의무적 인 블록 코드는 ... –

+0

아니, 나는 단지 궁금하다. Asyn은 윈도우의 환경에만 사용되기 때문에 Unix와 유사한 비 블로킹 소켓 메소드 인 Poll()을 사용하여이를 해결할 수있는 방법이있다. 이 작업이 Asyn 만 수행 할 수 있는지 조사 중이에요. :) – Roylee

1

메인 스레드를 차단하지 않고 연결을 시작하려면 threads 또는 tasks을 사용할 수 있습니다.

크로스 스레드 보호로 인해 UI (WinForms/WPF)와의 상호 작용이 필요할 경우 복잡성이 추가됩니다.

또한 BackgroundWorker을 사용하면이 문제를 피할 수 있습니다.

+1

작성자 질문 : "비동기 적으로 완료" –

+1

아니요, 그는 콜백 및 BeginConnect() 및 EndConnect()를 갖는 추가 된 Complexyti로 인해 비동기 메서드가 없다고 말합니다. 또는, 적어도, 이것은 내가 이해 한 것입니다. – JoanComasFdz

1

사실, 내 시스템에서 코드가 작동하고 있습니다. 그러나 TCP 연결을 허용하는 서버가 필요합니다. 당신이 그걸 가지고 있지 않다면, 당신은 영원히 기다릴 것입니다. 그래서 당신이 서버를 놓친 것 같아요.

관련 문제