2012-02-02 2 views
7

나는 거의 성공하지 못했습니다. this question에서 제안을 시도했습니다.2 개의 UDP 클라이언트를 하나의 포트에 연결 (보내기 및 받기)

제발 ... 어떤 도움을 주시면 대단히 감사하겠습니다!

여기 내 코드입니다 : 나는 당신의 오류 메시지가 고개를

static void Main(string[] args) 
{ 

    IPEndPoint localpt = new IPEndPoint(IPAddress.Any, 6000); 

    UdpClient udpServer = new UdpClient(localpt); 
    udpServer.Client.SetSocketOption(
     SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 

    UdpClient udpServer2 = new UdpClient(); 
    udpServer2.Client.SetSocketOption(
     SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 

    udpServer2.Client.Bind(localpt); // <<---------- Exception here 
} 
+1

을 시도 할 수 있습니다 해결하려면? –

+0

@ M.Babcock 예외 메시지 : "액세스 권한으로 금지 된 방식으로 소켓에 액세스하려고했습니다" – brooc

+0

'udpServer' 인스턴스가 바인딩을 시도 할 때 동일한 예외가 발생합니까? –

답변

23

바인딩하기 전에 소켓 옵션을 설정해야합니다.

static void Main(string[] args) 
    { 
     IPEndPoint localpt = new IPEndPoint(IPAddress.Any, 6000); 

     UdpClient udpServer = new UdpClient(); 
     udpServer.Client.SetSocketOption(
      SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 
     udpServer.Client.Bind(localpt); 

     UdpClient udpServer2 = new UdpClient(); 
     udpServer2.Client.SetSocketOption(
      SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 

     udpServer2.Client.Bind(localpt); // <<---------- No Exception here 

     Console.WriteLine("Finished."); 
     Console.ReadLine(); 
    } 

또는 더 예시 :

static void Main(string[] args) 
    { 
     IPEndPoint localpt = new IPEndPoint(IPAddress.Loopback, 6000); 

     ThreadPool.QueueUserWorkItem(delegate 
     { 
      UdpClient udpServer = new UdpClient(); 
      udpServer.ExclusiveAddressUse = false; 
      udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 
      udpServer.Client.Bind(localpt); 

      IPEndPoint inEndPoint = new IPEndPoint(IPAddress.Any, 0); 
      Console.WriteLine("Listening on " + localpt + "."); 
      byte[] buffer = udpServer.Receive(ref inEndPoint); 
      Console.WriteLine("Receive from " + inEndPoint + " " + Encoding.ASCII.GetString(buffer) + "."); 
     }); 

     Thread.Sleep(1000); 

     UdpClient udpServer2 = new UdpClient(); 
     udpServer2.ExclusiveAddressUse = false; 
     udpServer2.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 
     udpServer2.Client.Bind(localpt); 

     udpServer2.Send(new byte[] { 0x41 }, 1, localpt); 

     Console.Read(); 
    } 
+0

정말 고마워요 !!! 매력처럼 작동했습니다! – brooc

+0

다음 질문을 게시했습니다 : http://stackoverflow.com/questions/9140450/udp-hole-punching-implemetation-in-c-sharp – brooc

+0

왜'localpt'에'Bind'하고'Receive'에 'inEndPoint', 거기에 다른가요? (만약'localpt'에'Receive'가 없다면 아무 일도 일어나지 않을 것입니다.) – Benjol

2

이 오류가 무엇인지 설명하고 왜이 일어나고있다.

다음은 정확한 오류 메시지 및 이유 WSAEACCES 10013 (MSDN)

권한이 거부됩니다.

액세스 권한으로 금지 된 방식으로 소켓에 액세스하려고했습니다. 예를 들어 setsockopt (SO_BROADCAST)를 사용하여 브로드 캐스트 권한을 설정하지 않고 sendto에 대한 브로드 캐스트 주소를 으로 사용하고 있습니다.

다른 가능한 WSAEACCES 오류 이유는 바인드 기능 (윈도우 NT 나중에 SP4와 4.0에)가 호출 될 때 다른이 응용 프로그램, 서비스 또는 커널 모드 드라이버가 독점와 같은 주소에 바인드되고 있다는 점이다 접속하다. 이러한 단독 액세스는 Windows NT 4.0 SP4 이상의 새로운 기능 이며 SO_EXCLUSIVEADDRUSE 옵션을 사용하여 구현됩니다.

+0

고마워,하지만이 정보는 이미 찾아 냈어. 내 코드는 기본적으로 SO_EXCLUSIVEADDRUSE이지만 .NET 방식으로 가정하는 SocketOptionName.ReuseAddress를 사용합니다. 이 일을하는 데는 다른 방법이 필요 하겠지만, 찾을 수없는 것 같습니다. – brooc

+0

나는 이것이 좋은 퍼즐이 될 것입니다. 나는 올바른 길을 가고 있다고 생각합니다. 나는 도울 것입니다. 더 많은 것을 파헤 치고 코드도 시도해보십시오. 아마도 가장 단순한 코더가 보일 정도로 너무 단순합니다. – MethodMan

+0

고마워, 나는 이것을 하루 동안 보았습니다 ... 행운이 없습니다 ... 이것은 아마도 매우 간단한 작업 ...이 코드를 실행 해보십시오. – brooc

0

해도 나는 당신이 같은 포트에 바인딩 할 수없는 단 하나의 포트가 여기 를 사용할 수 있다는 표시되는 것과 동일한 오류 메시지를 취득하는 IP 주소를 전달할 수 있도록 코드입니다 변경 샘플 코드 나는이 죄송 .. 바인딩() 메소드에 예외를 생성합니다

 IPAddress ipAddress = Dns.Resolve(Dns.GetHostName()).AddressList[0]; 
     IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, 11000); 

     //IPEndPoint localpt = new IPEndPoint(ipLocalEndPoint); 

     UdpClient udpServer = new UdpClient(ipLocalEndPoint); 
     udpServer.Client.SetSocketOption(
      SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 
     udpServer.Connect(ipLocalEndPoint); 
     UdpClient udpServer2 = new UdpClient(); 
     udpServer2.Client.SetSocketOption(
      SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 

     udpServer2.Client.Bind(ipLocalEndPoint); // <<---------- Exception here 

.. 귀하의 예제를 사용하고 내 로컬 컴퓨터에서 내 IP를 캡처하는 데 변경된.

+0

거기에 있습니다. 이것을하는 방법이되어야합니다. 내 목표는 UDP 구멍 펀칭을 통합하는 시스템을 만드는 것입니다. 이것은 같은 포트를 통해 데이터를 보내고 있다는 사실에 의존합니다. – brooc

0

WSAEACCESS가 10013 UDP 응용 프로그램 (MSDN) 예외가 당신이 점점 어떤 예외

udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);