1 通讯 P2P
1.1
关键字【java udp 打洞】
参考文章 http://www.oschina.net/code/snippet_165555_17279
关键代码
package org.renlr.test;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPServer {
public static void main(String[] args) {
try {
DatagramSocket server = new DatagramSocket(2008);
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
String sendMessage132 = "";
String sendMessage129 = "";
int port132 = 0;
int port129 = 0;
InetAddress address132 = null;
InetAddress address129 = null;
for (;;) {
server.receive(packet);
String receiveMessage = new String(packet.getData(), 0, packet.getLength());
System.out.println(receiveMessage);
//接收到clientA
if (receiveMessage.contains("132")) {
port132 = packet.getPort();
address132 = packet.getAddress();
sendMessage132 = "host:" + address132.getHostAddress() + ",port:" + port132;
}
//接收到clientB
if (receiveMessage.contains("129")) {
port129 = packet.getPort();
address129 = packet.getAddress();
sendMessage129 = "host:" + address129.getHostAddress() + ",port:" + port129;
}
//两个都接收到后分别A、B址地交换互发
if (!sendMessage132.equals("") && !sendMessage129.equals("")) {
send132(sendMessage129, port132, address132, server);
send129(sendMessage132, port129, address129, server);
sendMessage132 = "";
sendMessage129 = "";
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void send129(String sendMessage132, int port132, InetAddress address132, DatagramSocket server) {
try {
byte[] sendBuf = sendMessage132.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendBuf, sendBuf.length, address132, port132);
server.send(sendPacket);
System.out.println("消息发送成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
private static void send132(String sendMessage129, int port129, InetAddress address129, DatagramSocket server) {
try {
byte[] sendBuf = sendMessage129.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendBuf, sendBuf.length, address129, port129);
server.send(sendPacket);
System.out.println("消息发送成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
package org.renlr.test;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
public class UDPClientB {
public static void main(String[] args) {
try {
//向server发起请求
SocketAddress target = new InetSocketAddress("10.1.11.137", 2008);
DatagramSocket client = new DatagramSocket();
String message = "I am UDPClientB 192.168.85.129";
byte[] sendbuf = message.getBytes();
DatagramPacket pack = new DatagramPacket(sendbuf, sendbuf.length, target);
client.send(pack);
//接收server的回复内容
byte[] buf = new byte[1024];
DatagramPacket recpack = new DatagramPacket(buf, buf.length);
client.receive(recpack);
//处理server回复的内容,然后向内容中的地址与端口发起请求(打洞)
String receiveMessage = new String(recpack.getData(), 0, recpack.getLength());
String[] params = receiveMessage.split(",");
String host = params[0].substring(5);
String port = params[1].substring(5);
System.out.println(host + ":" + port);
sendMessage(host, port, client);
} catch (Exception e) {
e.printStackTrace();
}
}
//向UPDClientA发起请求(在NAT上打孔)
private static void sendMessage(String host, String port, DatagramSocket client) {
try {
SocketAddress target = new InetSocketAddress(host, Integer.parseInt(port));
for (;;) {
String message = "I am master 192.168.85.129 count test";
byte[] sendbuf = message.getBytes();
DatagramPacket pack = new DatagramPacket(sendbuf, sendbuf.length, target);
client.send(pack);
//接收UDPClientA回复的内容
receive(client);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//收到UDPClientA的回复内容,穿透已完成
private static void receive(DatagramSocket client) {
try {
for (;;) {
//将接收到的内容打印
byte[] buf = new byte[1024];
DatagramPacket recpack = new DatagramPacket(buf, buf.length);
client.receive(recpack);
String receiveMessage = new String(recpack.getData(), 0, recpack.getLength());
System.out.println(receiveMessage);
//记得重新收地址与端口,然后在以新地址发送内容到UPDClientA,就这样互发就可以了。
int port = recpack.getPort();
InetAddress address = recpack.getAddress();
String reportMessage = "I am master 192.168.85.129 count test";
//发送消息
sendMessage(reportMessage, port, address, client);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void sendMessage(String reportMessage, int port, InetAddress address, DatagramSocket client) {
try {
byte[] sendBuf = reportMessage.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendBuf, sendBuf.length, address, port);
client.send(sendPacket);
System.out.println("send success");
} catch (Exception e) {
e.printStackTrace();
}
}
}