2014-06-23 4 views
1

디버깅 할 수없는 궁금한 점이 있습니다. 내 응용 프로그램이 특정 포트를 통해 UDP 패킷을 보내는 장치로부터 패킷을 받았습니다. UDP 수신기를 설정하면 while 루프가 Receive 명령을 주기적으로 트리거합니다.C# UDPClient에서 패킷을받지 못하는 응용 프로그램입니다. 수신

주어진 시간 간격마다 400 개의 값을 받아야하며이 값이 제대로 전달되는지 확인하기위한 프로세스도 설정해야합니다. 다음은 관련 코드의 단편이다

public UdpClient listener; 

IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort); 
//where listenPort is an int holding the port values should be received from 

listener.ExclusiveAddressUse = false; 
listener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 
listener.Client.Bind(groupEP); 

if (listener.Client.Connected) 
{ 
    listener.Connect(groupEP); 
} 
//I've actually never seen the app actually enter the code contained above 

try 
{ 
    while (!done) 
    { 
     if (isListenerClosed == false && currentDevice.isConnected) 
     { 
      try 
      { 
        receive_byte_array = listener.Receive(ref groupEP); 
      } 
      catch (Exception ex) 
      { 
        throw ex; 
      } 
     } 
    } 
} 
catch (SocketException ex) 
{ 
    throw ex; 
} 

이상한 점은 응용 프로그램이 내 PC에 잘 실행한다는 것입니다 (모두 설정 파일 /하면 Installshield를 통해 비주얼 스튜디오에서 실행할 때) 그러나 모든 데이터를받을 수 없습니다 동료의 컴퓨터에서 설치 파일을 실행하면 (Visual Studio 환경에서 올바르게 실행됩니다). 또한 Visual Studio를 앱의 프로세스에 연결하여 코드가 실행되어 listener.Receive에 도달 할 때까지 제대로 실행되었음을 발견했습니다. 예외가 잡히지 않으며 VS에서 오류가 발생하지 않지만 데이터가 수신되지 않으므로 코드가 중지됩니다.

부수적으로, 두 기계는 동일합니다 (Mac Minis는 64 비트 Windows 7 Ultimate N을 실행 함).

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 

private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
{ 
    MessageBox.Show("Unhandled Exception Caught " + e.ToString()); 
    throw new NotImplementedException(); 
} 

은 Windows에서 응용 프로그램 권한 문제가 될 수 다음과 같이

나는 심지어 메인 프로그램의 UnhandledExceptionHandler을 포함 시켰습니다? 문제를 찾아내는 최선의 방법에 대한 아이디어?

+2

아마도 방화벽 문제일까요? – oleksii

+1

방화벽은 실제로 UDP 연결은 차단하지만 인터넷 연결은 차단 한 것으로 보입니다. 그것을 간과하는 것에 어리석은 느낌. 감사합니다 @oleksii! – GroomedGorilla

답변

4

UDP는 연결없는 프로토콜입니다. Connect하지 마십시오. 대신 데이터 패킷을 전달하는 것입니다. 또한 UdpClient을 사용하는 경우 기본 소켓을 파 내려 가지 마십시오. 아무 소용이 없다.

간단한 (그리고 아주 바보) UDP 리스너는 다음과 같이 보일 것입니다 :

var listener = new UdpClient(54323, AddressFamily.InterNetwork); 

var ep = default(IPEndPoint); 

while (!done) 
{ 
    var data = listener.Receive(ref ep); 

    // Process the data 
} 

은 당신의 문제를 숨기는 역할을 ExclusiveAddressUse (및 SocketOptionName.ReuseAddress)의 주위에있는 모든 물건을. 브로드 캐스트 또는 멀티 캐스트를 사용하지 않는 한 해당 포트에서 UDP 리스너 중 하나만 메시지를 받게됩니다. 그것은 대개 나쁜 것입니다.

이 간단한 코드가 작동하지 않으면 배관을 점검하십시오. 방화벽, IP 주소, 드라이버 등. WireShark를 설치하고 UDP 패킷이 실제로 전달되는지 확인하십시오. 이는 장치의 잘못 일 수 있습니다. 잘못된 구성 일 수 있습니다.

또한이 모든 작업을 비동기 적으로 수행하는 것이 좋습니다. .NET 4.5를 사용한다면 실제로는 매우 쉽습니다.

+0

실제로 방화벽이 문제가되었습니다. 새로운 수신기 (세션 기반 앱)를 만들 때 socketExceptions을 계속 가져 왔기 때문에'ExclusiveAddressUse'에 추가했습니다. 이 방법을 연결하고 이후에 연결을 닫으면 한 세션을 종료하고 다른 세션을 시작할 때 얻은 문제점을 해결 한 것 같습니다. 이전에 장치에 문제가있었습니다. 결함이있는 구성 요소로 인해 예상보다 적은 패킷이 발생했지만 그 이후로 두 번 검사 했으므로 모두 정상입니다. 어쨌든 방화벽에 더 신뢰할 수있는 앱이 있는지 궁금합니다. – GroomedGorilla

+0

기본적으로 Windows 방화벽은 들어오는 모든 데이터를 차단합니다. 이를 변경하려면 설치 프로그램의 일부로 방화벽 규칙 변경을 포함시킬 수 있습니다. 그것이 모든 적절한 서버가하는 것입니다. 인터넷에 연결할 때 기본적으로 허용되는 아웃 바운드 연결을 만들고 있습니다 (TCP는 양방향이므로 인바운드 연결은 전혀 필요하지 않습니다). – Luaan

+0

이것이 올바른 대답이었습니다 :'Connect'를 호출하지 말고 Send() 함수에서 원격 주소와 포트를 보냅니다. 'udpClient.Send (dgram, dgram.Length, remoteEndPoint);' – kjhf

1

Windows Vista 이상 또는 이상에서 실행하는 경우 이는 아마도 UAC입니다. 소켓이 제대로 작동하는 것을 조용히 방지 할 수 있습니다. UAC 레벨을 낮추면 소켓을 막지 않습니다.

관련 문제