2016-06-07 2 views
2

C#에서 3 방향 UDP 구멍 펀칭 응용 프로그램을 작성하려고합니다. 내가 읽은 것부터, 그 단계는 다음과 같습니다.C# UDPClient는 모든 IP 주소를 받아들입니다.

  1. 는 피어 1은
  2. 피어 2는 서버에 연결 한 세부 사항
  3. 피어 2가 연결 1

피어 투 피어받을 서버

  • 서버 주 IP 주소 및 포트에 연결 내가 피어 1이 포트 8924의 서버에 연결하는 순간 서버는 원격 IP 주소 및 포트 세부 정보를 SQL 데이터베이스에 씁니다. 피어 2는 서버에 연결하여 세부 정보를 요청하면 피어 2는 얻은 세부 정보를 사용하여 새 UDP 클라이언트 및 IP 엔드 포인트를 만듭니다. 이 시점까지는 모든 것이 제대로 작동하지만 피어 2가 피어 1에 데이터를 보내면 아무 것도 도착하지 않습니다. > 서버, 서버 - -> 피어 1, 피어 2 -> 서버, 서버 -> 피어 2.

    그것은 피어 1은 메시지를 수락하지 않습니다 것처럼 나에게 보이는

    1은 피어를 연결에는 문제가 없다 서버가 아닌 다른 IP 주소.

    아래의 코드는 상당히 기본이지만 잘못된 부분을 생각할 수 있습니다. 누군가가 도망 칠 수 있다면, 나는 감사 할 것입니다.

    피어 1

    static void Main(string[] args) 
        { 
         int command = 0; 
         Random r = new Random(); 
         while (true) 
         { 
          UdpClient client = new UdpClient(); 
          IPEndPoint serverEndpoint = new IPEndPoint(IPAddress.Parse("xxx.xxx.xxx.xxx"), 8924); 
          client.Connect(serverEndpoint); 
          client.Send(BitConverter.GetBytes(command), 1); 
          Task.Run(() => { 
           byte[] data = client.Receive(ref serverEndpoint); 
           Console.WriteLine(ASCIIEncoding.ASCII.GetString(data)); 
           Console.ReadLine(); 
          }); 
          Console.WriteLine("sleep"); 
          Thread.Sleep(30000); 
          Console.WriteLine("resume"); 
    
         } 
    
        } 
    

    피어 2

    static void Main(string[] args) 
        { 
         while (true) 
         { 
          Console.WriteLine("press enter to start"); 
          Console.ReadLine(); 
          UdpClient getDetailsClient = new UdpClient(); 
          IPEndPoint getDetailsEndpoint = new IPEndPoint(IPAddress.Parse("xxx.xxx.xxx.xxx"), 8924); 
          getDetailsClient.Connect(getDetailsEndpoint); 
          getDetailsClient.Send(BitConverter.GetBytes(1), 1); 
          byte[] details = getDetailsClient.Receive(ref getDetailsEndpoint); 
          byte[] bIp = new byte[15]; 
          int port = BitConverter.ToInt32(details, 0); 
          Array.Copy(details, 4, bIp, 0, 15); 
          string Ip = ASCIIEncoding.ASCII.GetString(bIp).Trim(); 
          Console.WriteLine($"Address: {Ip} \tPort: {port}"); 
          UdpClient peerClient = new UdpClient(); 
          IPEndPoint endpointClient = new IPEndPoint(IPAddress.Parse(Ip), port); 
          peerClient.Connect(endpointClient); 
          peerClient.Send(ASCIIEncoding.ASCII.GetBytes("test"), 4); 
          Console.ReadLine(); 
         } 
    
        } 
    

    서버

    static void Main(string[] args) 
        { 
         int port = 8924; 
         IPEndPoint remote = new IPEndPoint(IPAddress.Any, port); 
         byte command; 
    
         UdpClient server = new UdpClient(port); 
         while(true) 
         { 
          //Wait on connection from client     
          var data = server.Receive(ref remote); 
          //get command 
          command = data[0]; 
          switch(command) 
          { 
           case (byte)0: 
            updateDatabase(ref server, ref remote); 
            break; 
           case (byte)1: 
            readDatabase(ref server, ref remote); 
            break; 
           default: 
            break; 
          } 
    
         } 
    
        } 
    
        private static void updateDatabase(ref UdpClient server, ref IPEndPoint remote) 
        { 
         Console.WriteLine("Write Command"); 
         using (dbDataContext db = new dbDataContext()) 
         { 
          ConnectionTB tb = db.ConnectionTBs 
           .Where(t => t.UniqueIdentifier.Trim().Equals("123456789")) 
           .Select(t => t) 
           .FirstOrDefault(); 
          tb.Port = remote.Port; 
          tb.IPAddress = remote.Address.ToString(); 
          tb.LastPing = DateTime.Now; 
          db.SubmitChanges(); 
          server.Send(ASCIIEncoding.ASCII.GetBytes(remote.Address.ToString().PadRight(15)),15,remote); 
         } 
        } 
    
        private static void readDatabase(ref UdpClient server, ref IPEndPoint remote) 
        { 
         Console.WriteLine("Read Command"); 
         using (dbDataContext db = new dbDataContext()) 
         { 
          ConnectionTB p = db.ConnectionTBs 
           .Where(c => c.UniqueIdentifier.Trim().Equals("123456789")) 
           .Select(c => c) 
           .FirstOrDefault(); 
    
          int port = p.Port.Value; 
          string ip = p.IPAddress.Trim(); 
          byte[] data = new byte[19]; 
          byte[] bPort = BitConverter.GetBytes(port); 
          byte[] bIp = ASCIIEncoding.ASCII.GetBytes(p.IPAddress.PadRight(15)); 
    
          Array.Copy(bPort, 0, data, 0, 4); 
          Array.Copy(bIp, 0, data, 4, 15); 
          server.Send(data, 19, remote); 
         } 
        } 
    
  • +0

    전에 본 적이 없기 때문에 물어볼 것입니다. IPAddress.Parse ("xxx.xxx.xxx.xxx") 란 무엇입니까? 실제로 엔드 포인트에 IP 주소를 어떻게 제공합니까? 나는 당신이 연결된 udp 소켓을 사용하고 있다는 사실을 중심으로이 문제가 발생한다고 생각합니다. –

    +0

    @user_ABCD - 표준 IP 주소 형식 (예 : "192.168.1.1")의 문자열 표현으로 IPAddress 객체를 만듭니다. 내 서버의 실제 IP 주소를 지우려면 'x'를 사용했습니다. – Chico

    +0

    HA, 바보 같은 날. 최선의 방법은 ip와 포트를 직접 연결 호출에 전달하는 것입니다. 그런 다음 client.Receive 호출 앞에 엔드 포인트를 작성하고 IPAddress.Any를 전달하십시오. –

    답변

    0

    @user_ABCD - 그것은 당신이 correc했다 밝혀 티. 내가 UDPCLient 대신 Sockets을 사용한다면 바인딩없이 "SendTo (EndPoint)"를 할 수 있습니다. 그러면 다음 보내기와 모든 작업을 위해 IP 주소/포트를 변경할 수 있습니다.

    감사합니다.

    관련 문제