मैं इसे अपने स्वयं के प्रोजेक्ट में करता हूं और पाया है कि यह समस्या जटिल नहीं है।
यहां नोड में एक बहुत ही सरल यूडीपी गूंज सर्वर है।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();
सामान्य संदेश और अपने खुद के वैश्विक आईपी & बंदरगाह प्राप्त करने के लिए भेज एंड्रॉइड क्लाइंट यूडीपी प्रेषक अन्य क्लाइंट के आईपी remoteHost
remotePort
का उपयोग कर प्रेषक
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();
एंड्रॉइड उपकरणों में कोई आंतरिक एनएटी जैसी चीज नहीं है। एक डिवाइस में एक या कई नेटवर्क होते हैं [इंटरफेस] (http://docs.oracle.com/javase/tutorial/networking/nifs/definition.html) और यदि आप सही पर सुन रहे हैं तो आप बाहर से कनेक्शन प्राप्त कर सकते हैं (मानते हुए आपके पास इंटरनेट अनुमति है)। यदि आप उस नेटवर्क के बीच नेटवर्क पथ की जांच नहीं कर सकते जो पहुंचने का प्रयास करता है और आपका डिवाइस। – zapl
एनएटी के पास अंतिम डिवाइस से कोई लेना देना नहीं है। डिवाइस को सिर्फ एक आईपी पता सौंपा गया है। चाहे वह एक रूटेबल है या नहीं, एक्सेस पॉइंट/डीएचसीपी सर्वर पर निर्भर करता है। –
यह अंत डिवाइस के साथ कुछ करने के लिए होना चाहिए। मोबाइल नेटवर्क इंटरफ़ेस पते के साथ सीधे पी 2 पी कनेक्शन का परीक्षण करते समय, यह पुराने एंड्रॉइड डिवाइस (एपिक 4 जी) से जुड़ा जुड़ाव करता है लेकिन गैलेक्सी एस 2 से कनेक्ट होने पर नहीं। NetworkInterface.getNetWorkInterfaces विधि द्वारा वापस गैलेक्सी का पता बाहरी आईपी से मेल नहीं खाता है जबकि एपिक 4 जी करता है। स्पष्ट रूप से फोन के नेटवर्किंग सेटअप के साथ कुछ बदल गया। – bgroenks