나는 내 프로젝트에서 그렇게하며이 문제가 복잡하지 않다는 것을 알았습니다.
다음은 노드에있는 매우 간단한 UDP 에코 서버입니다.
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);
JS 안드로이드 클라이언트는 단순히
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();
UDPholepunching
를 통해 일반 MSG와 자신의 글로벌 IP & 포트를 얻기 위해
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();
안드로이드 클라이언트 UDP의 청취자이 노드 서버에 MSG를 보내 다른 클라이언트의 IP를 사용하는 Android 클라이언트 UDP 발신자 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();
Android 기기에는 내부 NAT와 같은 것이 없습니다. 장치에는 하나 이상의 네트워크 [인터페이스]가 있습니다 (http://docs.oracle.com/javase/tutorial/networking/nifs/definition.html). 올바른 장치에서 수신하는 경우 외부에서 연결을 얻을 수 있습니다 (가정 인터넷 사용 권한이 있음). 액세스를 시도하는 네트워크 경로와 장치 사이의 네트워크 경로를 확인할 수없는 경우 – zapl
NAT는 최종 장치와 아무 관련이 없습니다. 장치에 IP 주소가 할당되었습니다. 라우팅 가능 여부는 액세스 포인트/DHCP 서버에 따라 다릅니다. –
최종 장치와 관련이 있어야합니다. 모바일 네트워크 인터페이스 주소로 직접 P2P 연결을 테스트 할 때 이전 Android 기기 (Epic 4G)에 연결하면 제대로 작동하지만 Galaxy S2에 연결하면 제대로 작동하지 않습니다. Epic 4G가하는 반면 NetworkInterface.getNetWorkInterfaces 메서드가 반환 한 은하의 주소는 외부 IP와 일치하지 않습니다. 분명히 전화기의 네트워킹 설정이 변경되었습니다. – bgroenks