2012-05-10 2 views
1

이렇게 대답 해 주시면 사과드립니다. 나는 보았지만 찾지 못했습니다. 제 상황은 고객이 로컬 네트워크에 연결하거나 Verizon 모뎀을 통해 원격으로 들어 와서 TCP 서버에 연결할 수 있다는 것입니다. (.NET 3.5 - C#을 사용 중입니다.)Socket.Connect 오류 및 오류 catch 할 수 없습니다.

그 중 하나에서 연결하면 문제가 없습니다. 하지만 내가 실수로 "잘못된"네트워크 (예 : 스타 벅스에 있고 무선 네트워크에 로그온 한 경우. 버라이즌 카드를 사용하고 있다고 생각하기 때문에 로그인하려고 시도합니다.)에서 서버가 연결. 벌금. 하지만 내 Try/Catch는 아무 것도 잡아 내지 못합니다 ... 스레드 풀을 통해 호출하는 경우 루틴을 종료하거나 직접 호출하면 중단됩니다. 여기

코드입니다 (이것은에 실패 m_clientSocket.Connect (IPEND)) :이은에라고

tcpConnectionObject passObject = new tcpConnectionObject(serverIP, serverPORT); 
     ThreadPool.QueueUserWorkItem(new WaitCallback(SRVR_CONNECT.connectToTCP), passObject); 

:

tcpConnectionObject passedTCPObject = (tcpConnectionObject) obj; 
if (checkNetStat(passedTCPObject) == false) 
{ 
    updateStatus(false); 
    return; 
} 

try 
{ 
    m_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
    IPAddress ip = IPAddress.Parse(passedTCPObject.ipString); 
    int iPortNo = System.Convert.ToInt16(passedTCPObject.portString); 
    IPEndPoint ipEnd = new IPEndPoint(ip, iPortNo); 

    m_clientSocket.Connect(ipEnd); 
    if (m_clientSocket.Connected) 
    { 
      updateStatus(true); 
      //Wait for data asynchronously 
      WaitForData(); 
    } 
} 
catch (SocketException e) 
{ 
    updateStatus(false); 
    return; 
} 
catch (Exception e) 
{ 
    updateStatus(false); 
    return; 
} 

updateStatus(true); 
return ; 

내가 스레드를 사용하여의 WinForm에서이 전화 양식의 SHOW() 메소드. 내가 이런 식으로 할 때, 내 양식을 보여 주지만 상태가 변경되지 않습니다 (어떤 결과가 있어야합니다) 내가 그것에 디버거를 넣고 실행을 단계별로 시작, 나는 Socket.Connect() 디버거가 단순히 mthod를 종료하면 내 양식이 표시됩니다. 나는 결코 내 어획량에 타격하지 않았다.

소켓에서 생성 할 수있는 모든 오류를 시도했지만 아무 것도 잡아 내지 못했습니다. 디버거를 실행하면 해당 행에 도달하자마자 내 메서드가 종료되지만 catch 가능 오류는 없습니다.

+0

당신이 당신이없이 백그라운드 스레드를 종료하는 것이 htink 왜 질문을 직접 호출하는 경우 교수형을 바탕으로 공고. 백그라운드 스레드도 걸려 있다고 가정합니다. – JaredPar

+0

디버거가 예외가 발생했을 때 중지되도록 설정 했습니까? –

+0

@IgbyLargeman이 내가 생각한 것을 확인하도록 제안했습니다. 단계별로 진행하면 예외가 적용되지 않습니까? – MStodd

답변

0

실제로 비동기 적으로 기다리고있는 경우 (주석에 명시된대로) 실제로 예외를 받기 전에 try/catch 블록을 종료 할 수 있습니다.

+0

그 라인에 도달하지 않는 것을 제외하고는 (나는 볼 수 있습니다.) 디버거를 단계별로 실행하면 연결이 끊어졌을 때 메소드가 종료됩니다. 디버거가 스레드 스레딩 객체에 의해 혼동되지 않으면 ... – MarkJoel60

+0

비동기 작업을 수행하는 경우 여러 스레드가 있습니다. 추적하기가 어렵습니다. WaitForData에서 수행중인 작업과 "비동기 적으로 데이터 대기"여부를 확인할 수 있습니까? –

+0

피터, 나는 네가 더 많거나 적은 권리라고 생각하기 때문에 너의 대답을 받아 들일 것이다. 나는 더 완전한 대답을 가지고 있지만, 너의 온전한 판단은 나를 올바른 길로 인도했다 ... – MarkJoel60

0

catch 블록 내부에 return 문이 있기 때문에 메서드가 종료됩니다. 당신은 명시 적으로 돌아 오라고 말하고 있습니다.

+0

예,하지만 모든 회신에 중단 점을 넣었으며 그 중 아무 것도 누르지 않았습니다. – MarkJoel60

0

좋아, 나는 Peter가 올바른 길에 있다고 생각한다. 디버거가 단순히 내 Connect 라인을 건너 뛰고 Socket.Connect()가 끝날 때까지 기다리는 동안 다음 줄로 넘어가는 것 같습니다 (0120).

다음은 작동하는 코드가 변경된 것입니다. .. "WaitForData"밖으로 패킷 생성 및 콜백 정의 이동 및 대신 beginConnect 메서드를 사용하십시오. 그 때 나는 내가 그것을 알 수 있습니다 실패 시간 제한을 설정할 수 있습니다 - 그래서 코드는이 변경됩니다 :

try 
     { 
      m_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
      // Cet the remote IP address 
      IPAddress ip = IPAddress.Parse(passedTCPObject.ipString); 
      int iPortNo = System.Convert.ToInt16(passedTCPObject.portString); 
      // Create the end point 
      ipEnd = new IPEndPoint(ip, iPortNo); 

      Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
      SocketPacket theSocPkt = new SocketPacket(); 
      if (m_pfnCallBack == null) 
      { 
       m_pfnCallBack = new AsyncCallback(OnDataReceived); 
      } 
      // Give It 5 Seconds to connect 
      IAsyncResult result = socket.BeginConnect(ipEnd, m_pfnCallBack, theSocPkt); 
      bool success = result.AsyncWaitHandle.WaitOne(5000, true); 

      if (!success) 
      { 
       socket.Close(); 
       throw new ApplicationException("Server Refused Connection"); 
      } 
      // Success 
      updateStatus(true); 
     } 
     catch (SocketException e) 
     { 
      updateStatus(false); 
      return; 
     } 
     catch (Exception e) 
     { 
      updateStatus(false); 
      return; 
     } 
관련 문제