Robię to w moim własnym projekcie i stwierdziłem, że ten problem nie jest aż tak skomplikowany.
Oto bardzo prosty serwer echa UDP w węźle.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);
android klient po prostu wysłać wiad z tym serwerem węzła
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();
Android Client UDP listner aby uzyskać ogólną wiad i własnego globalnego IP Port & poprzez 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();
Klient systemu Android Klient UDP używa innego klienta IP 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();
Na urządzeniach z Androidem nie ma wewnętrznych elementów typu NAT. Urządzenie ma jedną lub kilka sieci [interfejsów] (http://docs.oracle.com/javase/tutorial/networking/nifs/definition.html) i jeśli słuchasz tego, co właściwe, możesz uzyskać połączenia z zewnątrz (zakładając masz pozwolenie na Internet). Jeśli nie możesz sprawdzić ścieżki sieciowej między tą, która próbuje uzyskać dostęp do urządzenia. – zapl
NAT nie ma nic wspólnego z urządzeniem końcowym. Urządzenie ma właśnie przypisany adres IP. To, czy jest to rutowanie, zależy od punktu dostępowego/serwera DHCP. –
To musi mieć coś wspólnego z urządzeniem końcowym. Podczas testowania bezpośredniego połączenia P2P z adresem interfejsu sieci mobilnej działa dobrze łącząc się ze starszym urządzeniem z systemem Android (Epic 4G), ale nie podczas połączenia z Galaxy S2. Adres Galaxy zwracany przez metodę NetworkInterface.getNetWorkInterfaces nie pasuje do zewnętrznego adresu IP, podczas gdy Epic 4G to robi. Najwyraźniej coś się zmieniło w konfiguracji sieci telefonicznej. – bgroenks