2012-04-28 16 views
9

ऐसा लगता है कि नए एंड्रॉइड डिवाइस एनएटी के पीछे दौड़ते हैं, जहां स्थानीय पता एक आंतरिक वाहक या लैन पता है और सार्वजनिक पता राउटर या वाहक बाहरी पता सौंपा गया है।एंड्रॉइड: एनएटी ट्रैवर्सल?

फिर भी, नए फोन नेटवर्क इंटेरफेस का उपयोग करते हुए उसी पते को वापस नहीं करते हैं जब आईपी पहचान सेवा तक पहुंच होती है।

इसलिए, प्रत्यक्ष पी 2 पी सॉकेट चैनलों के माध्यम से कनेक्ट करना स्वाभाविक रूप से विफल रहता है।

क्या एंड्रॉइड मंच के लिए डिज़ाइन की गई इस समस्या के लिए कोई सामान्य कामकाज है? क्या कोई इस एनएटी जैसी सुरक्षा समस्या का कारण बन सकता है?

जावा NAT ट्रेवरसल ट्यूटोरियल या उदाहरण (नहीं निबंध या शोध करे) को भी लिंक भी उपयोगी किया जा रहा है (के रूप में मैं काफी यकीन है कि कैसे जावा में इसे लागू करने नहीं कर रहा हूँ) के रूप में की सराहना की जाएगी।

मैं निश्चित रूप से किसी भी अन्य समाधान को स्वीकार करने के लिए भी स्वीकार करूंगा!

+2

एंड्रॉइड उपकरणों में कोई आंतरिक एनएटी जैसी चीज नहीं है। एक डिवाइस में एक या कई नेटवर्क होते हैं [इंटरफेस] (http://docs.oracle.com/javase/tutorial/networking/nifs/definition.html) और यदि आप सही पर सुन रहे हैं तो आप बाहर से कनेक्शन प्राप्त कर सकते हैं (मानते हुए आपके पास इंटरनेट अनुमति है)। यदि आप उस नेटवर्क के बीच नेटवर्क पथ की जांच नहीं कर सकते जो पहुंचने का प्रयास करता है और आपका डिवाइस। – zapl

+0

एनएटी के पास अंतिम डिवाइस से कोई लेना देना नहीं है। डिवाइस को सिर्फ एक आईपी पता सौंपा गया है। चाहे वह एक रूटेबल है या नहीं, एक्सेस पॉइंट/डीएचसीपी सर्वर पर निर्भर करता है। –

+0

यह अंत डिवाइस के साथ कुछ करने के लिए होना चाहिए। मोबाइल नेटवर्क इंटरफ़ेस पते के साथ सीधे पी 2 पी कनेक्शन का परीक्षण करते समय, यह पुराने एंड्रॉइड डिवाइस (एपिक 4 जी) से जुड़ा जुड़ाव करता है लेकिन गैलेक्सी एस 2 से कनेक्ट होने पर नहीं। NetworkInterface.getNetWorkInterfaces विधि द्वारा वापस गैलेक्सी का पता बाहरी आईपी से मेल नहीं खाता है जबकि एपिक 4 जी करता है। स्पष्ट रूप से फोन के नेटवर्किंग सेटअप के साथ कुछ बदल गया। – bgroenks

उत्तर

0

मैंने अपने राउटर में कनेक्शन के दौरान उपयोग किए जा रहे सॉकेट को अग्रेषित करके सॉकेट स्थापित करने में कामयाब रहे हैं। यह मेरे लिए काम किया।

अद्यतन

cmd.exe के माध्यम से आपके आईपी पते यदि आपका अगर विंडोज (ipconfig) या एक टर्मिनल सत्र के माध्यम से उपयोग कर अपने लिनक्स (ifconfig) पर जानकारी प्राप्त करें। फिर ब्राउज़र के माध्यम से कनेक्ट करें और एक सुरक्षा खंड होना चाहिए। पोर्ट अग्रेषण पर जाएं और जब आप सर्वर सॉकेट और सॉकेट स्थापित करते हैं तो अपने पोर्ट्स को खोलें। प्रोटोकॉल के रूप में टीसीपी का प्रयोग करें। कृपया ध्यान दें कि यह केवल तभी लागू होता है यदि आप अपने वैलान से बाहर कनेक्ट करने का प्रयास कर रहे हैं।

+0

क्या आप एक उदाहरण विस्तृत या प्रदान कर सकते हैं? यह एक दिलचस्प अवधारणा की तरह लगता है। – bgroenks

+0

@ ghostsoldier23 मेरे अपडेट की जांच करें –

+3

ओह बस पोर्ट अग्रेषण? एनएटी ट्रैवर्सल का पूरा बिंदु इससे बचने के लिए है। – bgroenks

6

लगभग हर फोन या पीसी जो आप कभी भी छूएंगे, उसके पास एक स्थिर सार्वजनिक आईपी पता नहीं होगा, और इसलिए एनएटी ट्रैवर्सल की आवश्यकता होगी। यह डिवाइस की वजह से नहीं है; वाहक या आईएसपी आपके डिवाइस और सार्वजनिक इंटरनेट के बीच राउटर डालता है। आपके आवेदन के आधार पर, आमतौर पर एनएटी-ट्रैवर्सल लाइब्रेरीज़ आप उपयोग कर सकते हैं, जैसे कि ice4j या STUNT

+0

दोनों ice4j और स्टंट समर्थन केवल यूडीपी नहीं है? – bgroenks

4

मैं इसे अपने स्वयं के प्रोजेक्ट में करता हूं और पाया है कि यह समस्या जटिल नहीं है।

यहां नोड में एक बहुत ही सरल यूडीपी गूंज सर्वर है।js

var dgram = require('dgram'); 

var socket = 
    dgram.createSocket('udp4'); 

socket 
    .on('listening', function() 
    { 
     var address = socket.address(); 
     console.log('socket listening ' + 
      address.address + ':' + address.port); 
    }) 
    .on('error', function(err) 
    { 
     console.log('socket error:\n' + err.stack); 
     socket.close(); 
    }) 
    .on('message', function(message, rinfo) 
    { 
     console.log('message: ' + message + ' from ' + 
      rinfo.address + ':' + rinfo.port); 

     var msg = new Buffer(rinfo.address + ':' + rinfo.port); 
     socket 
      .send(msg, 0, msg.length, 
       rinfo.port, rinfo.address, 
       function(err, bytes) 
       { 
        //socket.close(); 
       }); 

    }) 
    .bind(15000); 

एक एंड्रॉयड ग्राहक बस एक संदेश इस नोड सर्वर से

     System.out.println("UDP hole punching======================="); 

         class IOth extends Thread 
         { 
          @Override 
          public void run() 
          { 

           String sendMsg = "UDP hole punching"; 
           byte[] buf = sendMsg.getBytes(); 
           DatagramPacket packet; 

           System.out.println(HPremoteHost); // node server IP 
           System.out.println(HPremotePort); // 15000 
           try 
           { 
            packet = 
              new DatagramPacket(buf, buf.length, 
                InetAddress.getByName(HPremoteHost), HPremotePort); 

            ds.send(packet); 


           } 
           catch (Exception e) 
           { 
            System.out.println("error================"); 
            System.out.println(e); 
           } 
          } 
         } 

         IOth io00 = new IOth(); 
         io00.start(); 

एंड्रॉयड क्लाइंट यूडीपी listner UDPholepunching

के माध्यम से
     class IOLoop extends Thread 
         { 
          @Override 
          public void run() 
          { 
           try 
           { 
            String msg = "Native.UDPserver.open"; 

            SocketAddress sockAddress; 
            String address; 


            byte[] buf = new byte[1024]; 
            DatagramPacket packet = new DatagramPacket(buf, buf.length); 
            while (true) 
            { 
             try 
             { 
              ds.receive(packet); 
              sockAddress = packet.getSocketAddress(); 
              address = sockAddress.toString(); 

              msg = new String(buf, 0, packet.getLength()); 

              System.out.println(msg + " received !!! by " + address); 

              //this case is UDP HolePunching reaction 
              if (address.equals(HPaddress1)) 
              { 
               System.out.println(msg + "hole punched"); 

               //So you can obtain own Global ip& port here. 
               //exchange this information 
               //`remoteHost` `remotePort` to another client 
               //with some method (signaling server) 

              } 
             } 
             catch (IOException e) 
             { 
             } 
            } 

           } 
           catch (Exception e) 
           { 
           } 
          } 
         } 

         IOLoop io00 = new IOLoop(); 
         io00.start(); 

सामान्य संदेश और अपने खुद के वैश्विक आईपी & बंदरगाह प्राप्त करने के लिए भेज एंड्रॉइड क्लाइंट यूडीपी प्रेषक अन्य क्लाइंट के आईपी remoteHostremotePort

का उपयोग कर प्रेषक
     class IOth extends Thread 
         { 
          @Override 
          public void run() 
          { 

           String sendMsg = "This is a test message"; 
           byte[] buf = sendMsg.getBytes(); 
           DatagramPacket packet; 

           try 
           { 
            packet = 
              new DatagramPacket(buf, buf.length, 
                InetAddress.getByName(remoteHost), remotePort); 

            ds.send(packet); 

           } 
           catch (Exception e) 
           { 

           } 
          } 
         } 

         IOth io00 = new IOth(); 
         io00.start(); 
+0

महान जवाब! यह मानते हुए कि यह काम करता है (-: – wires

+0

आपके द्वारा पोस्ट किए गए कोड का उद्देश्य क्या है? –

+0

उद्देश्य का जवाब देना है –

संबंधित मुद्दे