I have heard that using UDP to penetrate NAT can solve the problem of direct communication between two clients that access the Internet through NAT in P2P software. Of course, an intermediary is needed to help find the other party. Finally, I did this experiment using Java.
Paste the code.
UDPAgent. java:
Import java. io. BufferedReader;
Import java. io. InputStreamReader;
Import java.net. DatagramPacket;
Import java.net. DatagramSocket;
Import java.net. InetSocketAddress;
Import java.net. SocketAddress;
Import java. util. regex. Pattern;
/**
*
* @ Author Leo Luo
*
*/
Public class UDPAgent implements Runnable {
Public static void main (String [] args) throws Exception {
New UDPAgent (-1). start ();
}
DatagramSocket ds;
Byte [] recbuf = new byte [1, 1024];
DatagramPacket rec = new DatagramPacket (recbuf, recbuf. length );
Static String ipPattern = "([0-9] {1, 3}.) {3} [0-9] {1, 3 }";
Static String portPattern = "[0-9] {1, 5 }";
Static Pattern sendPattern = Pattern. compile ("send" + ipPattern + ""
+ PortPattern + ".*");
Int port;
Public UDPAgent (int port ){
This. port = port;
}
Public void init () throws Exception {
If (port <1024 | port> 655535 ){
Ds = new DatagramSocket ();
} Else {
Ds = new DatagramSocket (port );
}
}
Public void start () throws Exception {
Println ("start ");
Println ("LocalPort:" + port );
Init ();
New Thread (this). start (); // recive thread
Receive ();
}
Public void receive (){
For (;;){
Try {
Ds. receive (rec );
String msg = new String (rec. getData (), rec. getOffset (), rec
. GetLength ());
String line = rec. getSocketAddress () + ":" + msg;
Println (line );
OnReceive (rec );
} Catch (Exception e ){
E. printStackTrace ();
}
}
}
Public void onReceive (DatagramPacket rec ){
}
Public void doCommand (String cmd) throws Exception {
// Command:
// 1. send xxx. xxx *******************
If (sendPattern. matcher (cmd). matches ()){
DoSend (cmd );
}
}
Public void doSend (String cmd) throws Exception {
Println ("CMD:" + cmd );
String [] s = cmd. split ("", 4 );
Int port = Integer. parseInt (s [2]);
InetSocketAddress target = new InetSocketAddress (s [1], port );
Byte [] bs = s [3]. getBytes ();
DoSend (target, bs );
}
Public void doSend (SocketAddress addr, byte [] data) throws Exception {
DatagramPacket pack = new DatagramPacket (data, data. length, addr );
Ds. send (pack );
}
Public void run (){
BufferedReader reader = new BufferedReader (new InputStreamReader (
System. in ));
Try {
String line = reader. readLine ();
While (! "Exit". equals (line )){
DoCommand (line );
Line = reader. readLine ();
}
System. exit (0 );
} Catch (Exception e ){
E. printStackTrace ();
}
}
Public void println (String s ){
System. out. println (System. currentTimeMillis () + ":" + s );
}
}
UDPClient. java
____________________________________________________
Import java.net. DatagramPacket;
Import java.net. InetAddress;
Import java.net. InetSocketAddress;
Import java.net. SocketAddress;
Public class UDPClient extends UDPAgent {
/**
* @ Param args
*/
Public static void main (String [] args) throws Exception {
New UDPClient ("www.javadoc.cn", 2008,-1). start ();
}
String serverName;
Int serverPort;
SocketAddress server;
Public UDPClient (String host, int port, int localPort ){
Super (localPort );
This. server = new InetSocketAddress (host, port );
}
Public void start () throws Exception {
Println ("start ");
Init ();
Register ();
New Thread (this). start (); // recive thread
Receive ();
}
Public void onReceive (DatagramPacket rec ){
Try {
Report (rec );
If (rec. getSocketAddress (). equals (server )){
DoCommand (new String (rec. getData (), rec. getOffset (), rec
. GetLength ()));
}
} Catch (Exception e ){
E. printStackTrace ();
}
}
Public void report (DatagramPacket rec) throws Exception {
String s = rec. getSocketAddress ()
+ New String (rec. getData (), rec. getOffset (), rec. getLength ());
Byte [] buf = s. getBytes ();
Ds. send (new DatagramPacket (buf, buf. length, server ));
}
Public void register () throws Exception {
String msg = "register" + getLocalAddress () + "" + ds. getLocalPort ();
DoSend (server, msg. getBytes ());
}
Public String getLocalAddress () throws Exception {
InetAddress addr = InetAddress. getLocalHost ();
Return addr. getHostAddress ();
}
}
UDPServer. java
_______________________________________________________________
Public class UDPServer extends UDPAgent {
Public static void main (String [] args) throws Exception {
New UDPServer (2008). start ();
}
Public UDPServer (int port ){
Super (port );
}
}
1. Start a Server.
2. Start two clients.
Then, the NAT address and port of the two clients are displayed in the Console of the Server.
Enter the command "send a. a send B. B B hello" in the Server segment.
A. a is the NAT ip address and A port number of the first Client.
B is the second...
After entering this command, A will send B A hello directly. Sent successfully. If it is behind the same NAT address, A may have to send it to the Intranet address of B.
This article is from "yypiao"