`
kayo
  • 浏览: 560617 次
  • 性别: Icon_minigender_1
  • 来自: 安徽
社区版块
存档分类
最新评论

java NAT实现

阅读更多
早就听说用UDP穿透NAT可以解决P2P软件中的两个通过NAT上网的客户端直接通信的问题。当然,需要一个中介来帮助找到对方。终于用Java做了这个试验。

代码贴出来吧。

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[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.xxx.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。启动一个Server. 

2。启动两个Client. 

然后从Server端的Console里边可以看到两个Client的NAT后的地址和端口。

在Server段输入命令 send a.a.a.a A send b.b.b.b B hello

a.a.a.a是第一个Client的NAT后的ip,A端口号。

b是第二个。。。

输入这个命令后,A就会直接发给B一个 hello。 发送成功。 如果是同一个NAT后边,可能要让A发送到B的内网地址才能成功。
 
分享到:
评论
2 楼 wzpwork 2011-03-21  
如果没理解错误的话应该是下面这样的:

这个Server.java应该要在公网的服务器上运行,

UDPClient.java中的这行代码要适当修改下:
new UDPClient("www.javadoc.cn", 2008, -1).start(); 

将这行代码改为
new UDPClient(运行Sserver.java公网服务器IP, 2008, -1).start();

这样程序才能运行。

这里弱弱的问一下楼主,在这个NAT中,关键的是哪几句代码,帮忙注释一下,好让兄弟们更深入的了解。

谢谢!
1 楼 mj4678 2009-10-23  
楼主,为什么我用你的测试一直么通过呢。。。。能否给个完整的测试程序参考下。。
178513351@qq.com

相关推荐

    Java实现UDP穿透NAT技术

    Java提供了一种方式来实现UDP NAT穿透,通过创建一个服务器端和客户端应用程序,可以协助位于NAT后的设备之间建立直接通信。以下是实现这一技术的一些关键知识点: 1. **STUN(Traversal Using Relays around NAT)...

    Java NAT穿越

    在Java中实现NAT穿越,主要是利用STUN(Session Traversal Utilities for NAT)协议或者ICE(Interactive Connectivity Establishment)协议。STUN服务器可以用来帮助客户端发现其公网IP和端口,而ICE则是一种更为...

    java udp p2p nat 等打洞技术实现通信,已测试成功

    总结,通过Java实现的UDP打洞技术,可以克服NAT的障碍,实现子网间的P2P通信。这在分布式系统、在线游戏、文件共享等领域都有广泛应用。在实际开发中,还需要考虑兼容性、安全性以及网络环境的复杂性。

    NAT.rar_NAT_NAT JAVA_java nat_nat

    Java中的NAT实现主要涉及到网络编程,尤其是在处理分布式系统、P2P网络或者需要穿透NAT的场景时。Java提供了一些API来处理这些问题,如MulticastSocket和DatagramSocket,它们可以帮助开发者发送和接收UDP数据包,...

    Nat.zip_NAT java_java nat

    【标签】"java"和"java_nat"进一步确认了这个压缩包的内容是以Java编程语言实现的NAT相关的程序。Java是一种广泛使用的面向对象的编程语言,以其“一次编写,到处运行”的特性著称,适合开发跨平台的网络应用。 ...

    NAT探测 使用stun协议 java和python版本

    Java中的"stun4j"库是一个用于STUN和TURN(Traversal Using Relays around NAT)服务的客户端库,提供了处理NAT穿透所需的基本功能。开发者可以使用stun4j来创建STUN请求,解析响应,从而获取到必要的网络信息。 ...

    STUN协议的java实现,stun4j

    stun4j是Java编程语言中实现STUN协议的一个开源库,它为开发者提供了简单易用的API,以便在Java应用中集成NAT穿透功能。stun4j包含了以下主要组件和功能: 1. **STUN客户端(STUNClient)**:这是核心组件,负责...

    NAT穿透java

    标题“NAT穿透Java”指的是在Java编程环境中实现网络地址转换(NAT)穿透的技术,主要针对UDP协议。NAT穿透对于实现内网设备之间的通信至关重要,因为常规的NAT设置会阻止直接的端对端连接。在此场景下,描述中提到...

    基于 Java 的 NAT 软交换代理及存储集群系统研究

    为此,探讨 NAT 种类、应用及核心思想,及用 Java 网络包 java.net 实现 NAT 软交换的思路和方法,并根据网络存储系统安全问题,提出基于 NAT 的存储集群架构,分析其运行机制算法。模拟测试结果表明,基于 NAT 可在...

    JAVA穿越NAT

    "JAVA穿越NAT"这一主题涉及到了如何在Java环境中实现在网络地址转换(Network Address Translation, NAT)下的点对点(P2P, Peer-to-Peer)UDP通信。NAT通常被用来让多个内部网络设备共享一个公共IP地址访问外部网络...

    基于Java的NAT软交换代理及存储集群系统研究.pdf

    本文研究基于Java的NAT软交换代理及存储集群系统,讨论了NAT的种类、应用及核心思想,并使用Java网络包java.net实现了NAT软交换的思路和方法。同时,根据网络存储系统安全问题,提出了基于NAT的存储集群架构,分析了...

    P2p之UDP穿透NAT的原理与实现代码

    在提供的压缩包中,"P2P之UDP穿透NAT的原理与实现源代码"很可能是用某种编程语言(如C++、Python或Java)实现的示例代码,包含具体的打洞算法和信令交互逻辑。通过阅读和理解这些代码,可以更深入地了解UDP穿透NAT的...

    udp.zip_ICE NAT_UDP nat java_nat_udp打洞_最新防火墙

    就是非常有名的“UDP打洞技术”,UDP打洞技术依赖于由公共防火墙和cone NAT,允许适当的有计划的端对端应用程序通过NAT“打洞”,即使当双方的主机都处于NAT之后。这种技术在 RFC3027的5.1节[NAT PROT] 中进行了重点...

    自动NAT检测STUN源代码.rar_nat stun_nat 类型_nat在线检测_nat检测_网络类型

    而“stund”可能是指STUN服务器的实现,通常是一个守护进程(daemon),负责处理来自客户端的STUN请求。 总的来说,这个压缩包包含的源代码可能是用于创建一个工具,该工具能够自动检测用户所在的NAT类型,这将有助...

    Java 穿越NAT方案 JSTUN.tar

    JSTUN,全称为Java Simple Traversal of User Datagram Protocol (UDP) Through NAT,是Java语言编写的一个STUN(简单穿越NAT)协议的实现。STUN是一种IETF标准,它允许内网设备发现其在公网中的映射地址和端口,...

    飞鸽的java实现版

    在飞鸽的Java实现中,了解如何建立P2P连接,包括端口映射、NAT穿透等技术至关重要。 3. **套接字编程**:Java中的Socket编程用于在网络中实现两台计算机之间的通信。开发者需要熟悉ServerSocket和Socket类,以及...

    WebRTC+java实现多人视频通讯

    在“WebRTC+Java实现多人视频通讯”的项目中,WebRTC主要负责前端的音视频采集、编码、传输和解码工作。用户可以在浏览器中直接参与视频通话,得益于WebRTC的API,开发者可以轻松获取用户的摄像头和麦克风权限,并...

    真正好用的nat穿透源代码,附送STUN检测代码

    NAT(网络地址转换)穿透技术就是为了在NAT环境下实现设备间的直接通信而设计的。本文将深入探讨NAT穿透的基本原理以及提供的源代码。 NAT是一种普遍应用于家庭和企业网络的技术,它允许一个或多个设备共享一个...

    Java 穿越NAT方案 JSTUN.7z

    总的来说,Java中的JSTUN库提供了一种实现NAT穿透的方法,这对于开发分布式系统、P2P应用或者VoIP服务等需要跨NAT通信的应用非常有价值。开发者可以通过理解STUN协议和JSTUN库的工作原理,结合实际网络环境,来实现...

Global site tag (gtag.js) - Google Analytics