package socket.Stun.simple.ns.s;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.util.Timer;
import java.util.TimerTask;
public class S {
/**
* @param args
* @throws IOException
*/
/**
* @param args
* @throws IOException
* @throws InterruptedException
*/
public static void main(String[] args) throws IOException,
InterruptedException {
final DatagramSocket udpsocket = new DatagramSocket(42000);
udpsocket.setReuseAddress(true);
System.out.println(" 等待NS注册和NC指令");
// 等待NS注册和NC指令
SocketAddress NSaddress = null;
boolean end = false;
try {
while (end == false) {
byte[] buf = new byte[1024];
DatagramPacket udp = new DatagramPacket(buf, buf.length);
udpsocket.receive(udp);
String msg = new String(udp.getData());
if (msg.startsWith("NS:")) {
NSaddress = udp.getSocketAddress();
System.out.println("收到来自NS" + NSaddress + "的注册");
System.out.println(new String(udp.getData()));
String respNS = "NS:" + udp.getAddress() + ":"
+ udp.getPort();
DatagramPacket repNSudp = new DatagramPacket(respNS
.getBytes(), respNS.getBytes().length, NSaddress);
udpsocket.send(repNSudp);
udpsocket.send(repNSudp);
udpsocket.send(repNSudp);
// 检测客户端保持活动
TimerTask checkNSalive = new TimerTask() {
@Override
public void run() {
try {
byte[] buf = new byte[1024];
DatagramPacket udp = new DatagramPacket(buf,buf.length);
udpsocket.receive(udp);
System.out.println("收到客户端用来保持连接存活的消息:"+new String(udp.getData()));
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
};
new Timer().schedule(checkNSalive, 0, 20 * 1000);
System.out.println("输入S->NS的消息");
BufferedReader localin = new BufferedReader(
new InputStreamReader(System.in));
respNS = null;
while (respNS == null) {
respNS = localin.readLine();
}
int moments = 6;
while (true) {
repNSudp = new DatagramPacket((respNS+":延迟"+moments+"分钟").getBytes(), (respNS+":延迟"+moments+"分钟")
.getBytes().length, NSaddress);
udpsocket.send(repNSudp);
udpsocket.send(repNSudp);
udpsocket.send(repNSudp);
Thread.sleep(60 * 1000 * moments);
moments+=1;
}
} else {
System.out.println(new String(udp.getData()));
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
package socket.Stun.simple.ns.s;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.Timer;
import java.util.TimerTask;
public class NS {
/**
* @param args
* @throws IOException
*/
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
if(args.length<1){
System.out.println("usage: NS 172.16.253.123");
return;
}
String stunIp = args[0];
int stunPort = 42000;
final InetSocketAddress Saddress = new InetSocketAddress(stunIp, stunPort);
final DatagramSocket udpsocket = new DatagramSocket(42001);
udpsocket.setReuseAddress(true);
System.out.println("Sotimeout:"+udpsocket.getSoTimeout());
String outAddress = null;
String NSname = "NS:" ;
DatagramPacket udp = new DatagramPacket(NSname.getBytes(), NSname
.getBytes().length, Saddress);
udpsocket.send(udp);
udpsocket.send(udp);
udpsocket.send(udp);
while (true) {
byte[] buf = new byte[1024];
DatagramPacket reged = new DatagramPacket(buf, buf.length);
udpsocket.receive(reged);
System.out.println("收到消息。");
if(udp.getSocketAddress().equals(Saddress)){
System.out.println("\t收到S的消息。");
outAddress = new String(udp.getData());
if (outAddress.startsWith("NS:")) {
System.out.println("\t\t收到S确认注册的消息。");
outAddress = outAddress.substring(3);
break;
}
}
}
System.out.println("注册成功。外网地址为:" + outAddress);
// 2保持映射活动
TimerTask keepalive = new TimerTask() {
@Override
public void run() {
try {
DatagramPacket udp = new DatagramPacket("NS:hello S,"
.getBytes(), "hello S,".getBytes().length,
Saddress);
udpsocket.send(udp);
System.out.println("keepalive");
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
new Timer().schedule(keepalive, 0, 20 * 1000);
// 3等待指令S->NS
while (true) {
byte[] buf = new byte[1024];
udp = new DatagramPacket(buf, buf.length);
udpsocket.receive(udp);
if (udp.getSocketAddress().equals(Saddress)) {
System.out.println("收到" + udp.getSocketAddress() + "的数据:"
+ new String(udp.getData()));
String msg = new String(udp.getData());
System.out.println("S:"+msg);
}
}
}
}
分享到:
相关推荐
本篇将详细介绍UDP穿透NAT的原理,并探讨C#实现这一功能的方法。 1. UDP与NAT的基本概念: - UDP:是一种无连接的传输层协议,不保证数据包的顺序、完整性和可靠性,但提供了更快的数据传输速度。 - NAT:在网络...
本文将深入探讨UDP穿透NAT的原理以及其实现方法。 NAT工作原理: NAT的主要作用是将内部网络的私有IP地址映射为外部网络的公共IP地址,从而解决IP地址短缺的问题。当内部主机向外部发送数据时,NAT会记录源IP和端口...
对于压缩包中的"UDP穿透"文件,这可能包含了实现上述过程的源代码示例,你可以通过阅读和分析代码,更深入地理解UDP穿透打洞的原理和C#实现细节。 总结来说,C#实现UDP穿透打洞涉及了网络编程、NAT工作原理、STUN/...
"穿透"这个词多次出现,进一步确认了这个工具的核心特性就是提供穿透内网的能力。内网穿透通常分为几种类型,比如基于NAT穿透的UDP hole punching,STUN,TURN等方法,或者是基于HTTP代理、SSH隧道等技术。PHP实现的...
总的来说,P2P UDP穿透NAT是一项复杂的技术挑战,需要理解NAT的工作原理,利用STUN和TURN服务器,以及采用ICE等策略来建立可靠的端到端连接。尽管存在难度,但通过这些方法,我们可以让分布在世界各地的设备之间实现...
以上就是关于“Java实现UDP穿透NAT技术”的一些核心知识点,实际的代码实现会根据具体的需求和环境有所不同,但基本思路和上述内容是相似的。通过理解这些原理和Java中的实现细节,你可以构建自己的NAT穿透解决方案...
在创建NAT穿透测试程序时,开发者需要编写客户端和服务器端的代码,处理UDP数据包的收发,并根据NAT类型和配置调整连接策略。 在C#中,创建UDP套接字并监听或发送数据的基本步骤包括: 1. 创建`UdpClient`实例,...
在P2P网络中,UDP穿透NAT是一种关键的技术,用于让两个位于不同网络环境(如家庭、公司网络等)的设备能够直接通信,而无需通过中心服务器作为中介。NAT(网络地址转换)通常会阻止这种直接通信,因为每个设备在内网...
这个Demo展示了如何利用UDP协议穿透NAT,使内网设备能够直接通信。 描述中提到,这是原作者经过改进的最完善版本,相比于之前的“基于UDP的P2P小Demo (穿透NAT)delphi源码”,它更加成熟和完善,具备更高的参考价值...
标题中的“P2P之UDP穿透NAT的原理与C#实现”主要涉及两个关键概念:P2P(peer-to-peer)网络技术和UDP(User Datagram Protocol)在NAT(Network Address Translation)环境下的穿透技术。这里我们将深入探讨这两个...
第一个连接上服务器的客户端,称为client1,第二个连接上服务器的客户端称为client2 这个程序的功能是:先连接上服务器,根据服务器的返回决定它是client1还是client2, 若是client1,它就从服务器上得到client2的IP...
标题 "P2P之UDP穿透NAT的原理与实现(增强篇)" 指向的是一个关于如何在P2P网络中通过UDP协议穿透NAT(网络地址转换)的技术主题。NAT是互联网上广泛使用的一种技术,它允许一个内部网络中的多个设备共享一个公共IP...
为了实现P2P中的UDP穿透NAT,我们需要理解几种主要的穿透方法: 1. **UDP打洞(UDP Hole Punching)**:这种方法依赖于NAT的一致性行为,即当一个内网主机向公网发送数据后,NAT通常会记住这个映射,允许来自同一...
dotnet core UDP穿透内网客户端 非源码,但未加密 打洞实现 1、开一个云服务器,或自家的宽带,全主机映射。 2、云控制台上安全组udp打开相应的端口,打开防火墙上相应的端口。 3、两台客户端。。 4、A通过Udp...
本资料主要探讨NAT穿透内网的相关知识点,并提供了源代码供学习者参考。 **NAT工作原理** NAT的核心功能是将内部网络的私有IP地址转换成公有IP地址,以便外部网络可以访问。当内部设备发起对外部的连接请求时,NAT...
本资源“P2P 之 UDP穿透NAT的原理与实现(附源代码)P2PServer.rar”旨在详细介绍如何通过UDP协议穿透NAT,实现P2P网络中的节点间通信。下面将详细讲解这个主题。 首先,我们要理解NAT的工作原理。NAT允许私有网络...
3. **STUN(Simple Traversal of UDP through NATs)协议**:STUN服务器可以用来帮助内网设备发现自己的公网IP和端口,是UDP穿透的重要工具。易语言中可能需要通过HTTP请求获取STUN服务器响应,解析IP和端口信息。 ...
UDP穿透的基本思想是利用UDP的多对多映射特性,让内网设备通过与公网服务器交互,获取对方的NAT映射信息,从而直接建立连接。 易语言的源码示例可能包括以下关键部分: 1. UDP套接字创建:创建UDP套接字,用于接收...
本文将深入探讨UDP穿透NAT的原理以及实现方法,并提供源代码供参考。 1. UDP穿透NAT原理: - NAT工作原理:NAT设备会记录内网设备与公网的通信,将内网私有IP地址映射到公网IP地址,同时为每次会话分配一个端口号...
UDP打洞就是为了解决这个问题,让两个内网设备能够直接交换数据,而无需通过服务器作为中介。 首先,我们要理解UDP(用户数据报协议)的特点。UDP是一个无连接的、不可靠的传输协议,它不保证数据包的顺序和完整性...