我在自己的项目中也做了这件事,并发现这个问题并不那么复杂。
以下是一个非常简单的Node.js 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)
{
});
})
.bind(15000);
一个Android客户端只需向此节点服务器发送一条消息。
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);
System.out.println(HPremotePort);
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客户端UDP监听器,通过UDPholepunching获取通用消息和您自己的全局IP&端口
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);
if (address.equals(HPaddress1)) {
System.out.println(msg + "hole punched");
}
} catch (IOException e) {
}
}
} catch (Exception e) {
}
}
}
IOLoop io00 = new IOLoop();
io00.start();
使用其他客户端的IP remoteHost
和端口号remotePort
发送Android客户端UDP。
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();