udp内网穿透 两个内网互联
1,在有外网ip的机器上启动server。
package udp; import java.net.DatagramPacket;
import java.net.InetSocketAddress; public class Server extends UDPAgent {
public static void main(String[] args) throws Exception {
new Server(2008).start();
} public Server(int port) {
super(port);
} public void onReceive(DatagramPacket rec) {
try {
println("=== Server OnReceive ===");
String s = rec.getSocketAddress().toString();
String msg = new String(rec.getData(), rec.getOffset(),
rec.getLength());
//if receive client's first log on, return its NAT port.
if (msg.trim().startsWith("register")) {
DatagramPacket outPacket = new DatagramPacket(s.getBytes(),
s.length(), rec.getSocketAddress());
// 发送数据 ds.send(outPacket);
}
} catch (Exception e) {
e.printStackTrace();
}
} public void doSend(String cmd) throws Exception {
println("====server's doSend=====");
println("CMD: " + cmd);
String[] s = cmd.split(" ", 4);
// println("===split cmd=========");
// for(String item:s){
// println(item);
// }
// println("============");
int port = Integer.parseInt(s[2]);
InetSocketAddress target = new InetSocketAddress(s[1], port);
String msg = s[0]+" "+s[3];
doSend(target, msg.getBytes());
}
}
2,在内网启动2个client。
package udp; import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Timer;
import java.util.TimerTask; public class Client extends UDPAgent {
private static final long INTERVAL_TIME = 1 * 20 * 1000; SocketAddress server; //
/**
* @param args
*/
public static void main(String[] args) throws Exception {
String ip = "211.100.75.221";
int serverPort = 2008;
if (args.length > 0) {
ip = args[0];
}
if (args.length > 1) {
serverPort = Integer.parseInt(args[1]);
}
new Client(ip, serverPort, -1).start();
} public Client(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
new HeartBeat(); // dead loop
receive();
// Cannot reach here.
} public void onReceive(DatagramPacket rec) {
try {
println("=== Client onReceive ==="); //if message not from server, then report to server.
// if (!rec.getSocketAddress().equals(server)) {
report(rec);//client should return status in order to tell server command execute result.
// } String receivedMsg = new String(rec.getData(), rec.getOffset(),
rec.getLength());
//if the received message is from server, do server's command.
if (rec.getSocketAddress().equals(server)) {
doCommand(receivedMsg);
}else{
println("Received from other client: "+receivedMsg);
} } catch (Exception e) {
e.printStackTrace();
}
} public void report(DatagramPacket rec) throws Exception {
String s = "Report: from " + rec.getSocketAddress() + " messgae:"
+ new String(rec.getData(), rec.getOffset(), rec.getLength());
byte[] buf = s.getBytes();
println("Report to server");
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();
} public void doSend(String cmd) throws Exception {
println("====client doSend=====");
println("CMD: " + cmd);
String[] s = cmd.split(" ", 4);
// println("===split cmd=========");
// for(String item:s){
// println(item);
// }
// println("============");
int port = Integer.parseInt(s[2]);
InetSocketAddress target = new InetSocketAddress(s[1], port);
String msg = s[3];
doSend(target, msg.getBytes());
} class HeartBeat { private Timer timer; public HeartBeat() {
println("heartbeat start.");
try {
this.timer = new Timer(); this.timer.schedule(new ConnSvrTask(), 1000, INTERVAL_TIME); } catch (Exception e) {
e.printStackTrace();
}
} private class ConnSvrTask extends TimerTask { public ConnSvrTask() {
super();
} public void run() {
try {
byte[] b = "skip".getBytes();
DatagramPacket packet = new DatagramPacket(b, b.length);
// 发送心跳
// println("heartbeat");
packet.setSocketAddress(server);
ds.send(packet);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
3,他们共同的父类文件
package udp; import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.text.SimpleDateFormat;
import java.util.Date;
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);
}
println("====Address info======");
println("InetAddress.getLocalHost: " + InetAddress.getLocalHost());
println("connect getLocalPort:" + ds.getLocalPort());
println("getLocalAddress: " + ds.getLocalAddress().getHostAddress());
println("connect getPort:" + ds.getPort());
println("getInetAddress: " + ds.getInetAddress());
println("getLocalSocketAddress: " + ds.getLocalSocketAddress());
println("getRemoteSocketAddress: " + ds.getRemoteSocketAddress());
println("======================="); } public void start() throws Exception {
println("start");
println("LocalPort:" + port);
init();
new Thread(this).start();// recive thread
receive();
} public void receive() {
for (;;) {
try {
// println("Waiting...");
ds.receive(rec);
String msg = new String(rec.getData(), rec.getOffset(),
rec.getLength());
if (msg.equals("skip"))
continue;
//skip heartbeat print out receive.
println("=== UDP Agent receive ===");
String line = "Received from " + 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()) {
if (cmd.startsWith("send")) {
doSend(cmd);
}
} public void doSend(String cmd) throws Exception {
println("CMD: " + cmd);
String[] s = cmd.split(":", 4);
// println("===split cmd=========");
// for(String item:s){
// println(item);
// }
// println("============");
int port = Integer.parseInt(s[2]);
InetSocketAddress target = new InetSocketAddress(s[1], port);
byte[] bs = "Say Hello!".getBytes();
doSend(target, bs);
} public void doSend(SocketAddress addr, byte[] data) throws Exception {
println("target:" + addr); 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();
}
} SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd H:m:s"); public void println(String s) {
System.out.println(format.format(new Date()) + ": " + s);
}
}
在服务器端输入指令,根据连接上来的两个客户端ip:
send 192.168.11.100 57771 192.168.11.100 57768 message here
即让第一个客户端给第二个发送消息。
如果共同位于同一个nat后,ping不同彼此的ip。需要指定内网ip。服务器如何获取不知道。
udp内网穿透 两个内网互联的更多相关文章
- 【网络】内网穿透方案&FRP内网穿透实战(基础版)
目录 前言 方案 方案1:公网 方案2:第三方内网穿透软件 花生壳 cpolar 方案3:云服务器做反向代理 FRP简介 FRP资源 FRP原理 FRP配置教程之SSH 前期准备 服务器配置 下载FR ...
- frp内网 穿透映射使内网svn可外网访问
起因 公司svn目前部署在内网服务器上,现在想在家中也可以使用,因此需要外网访问内网的工具 经过 使用过几个产品: utools,一个小巧的windows下的工具,内网映射只是它的一个小功能,支持tc ...
- 基于C#的内网穿透学习笔记(附源码)
如何让两台处在不同内网的主机直接互连?你需要内网穿透! 上图是一个非完整版内外网通讯图由内网端先发起,内网设备192.168.1.2:6677发送数据到外网时候必须经过nat会转换成 ...
- QuantumTunnel:内网穿透服务设计
背景 最近工作中有公网访问内网服务的需求,便了解了内网穿透相关的知识.发现原理和实现都不复杂,遂产生了设计一个内网穿透的想法. 名字想好了,就叫QuantumTunnel,量子隧道,名字来源于量子纠缠 ...
- frp 用于内网穿透的基本配置和使用
frp 用于内网穿透的基本配置和使用 今天是端午节,先祝端午安康! frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP.UDP.HTTP.HTTPS 等多种协议.可以将内网服务以安全.便 ...
- 基于4G Cat.1的内网穿透实例分享
上一篇分享了:小熊派4G开发板初体验 这一篇继续BearPi-4G开发板实践:内网穿透实验. 基本TCP的socket通信测试 之前我们学习WiFi模块时,与PC进行TCP协议的socket通信测试我 ...
- frp实现内网穿透
frp实现内网穿透 目标 通过外网访问内网设备,本文中实现通过手机的移动流量,可以访问到树莓派设备 设备准备 需要被访问的设备(本文中使用Raspberry Pi`).公网IP设备(本文中使用阿里云 ...
- SSH 端口转发+内网穿透
用最直白的语言对本文所有内容进行定义: 端口转发(-L):用A机器(内网)登录B机器(公网), 在A机器打开端口,将收到的所有请求转发到B机器的某个端口 (在代理机上执行) 内网穿透(-R):用A机器 ...
- SSH的内网穿透
SSH的内网穿透 1.内网: ssh -N -f -R 2222:127.0.0.1:22 lienzh@我的PC的IP2.外网: ssh -p 2222 root@localhost ...
随机推荐
- Java虚拟机工作原理详解 ( 二 )
首先这里澄清两个概念:JVM实例和JVM执行引擎实例,JVM实例对应了一个独立运行的Java程序,而JVM执行引擎实例则对应了属于用户运行程序的线程:也就是JVM实例是进程级别,而执行引擎是线程级别的 ...
- js原生捕鱼达人(三)--完结
先给分享下我写完的效果,github有点卡,我没有压缩代码,不过效果可以看到 https://jasonwang911.github.io/ 转载请注明'转载于Jason齐齐的博客http://www ...
- (copy)MVC4.0网站发布和部署到IIS7.0上的方法
最近在研究MVC4,使用vs2010,开发的站点在发布和部署到iis7上的过程中遇到了很多问题,现在将解决的过程记录下来,以便日后参考,整个过程主要以截图形式呈现 vs2010的安装和mvc4的安装不 ...
- javascript中的array对象属性及方法
Array 对象 Array 对象用于在单个的变量中存储多个值. 创建 Array 对象的语法: new Array(); new Array(size); new Array(element0, e ...
- 第二章 rabbitmq在mac上的安装
下载页: http://www.rabbitmq.com/install-standalone-mac.html 1.下载页面首部的文件(页面下载可能比较慢,使用迅雷下载就好),之后解压到一个合适的路 ...
- C++ STL之vector详解
转自http://blog.sina.com.cn/s/blog_9f1c0931010180cy.html Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作 ...
- no.5.print sum
#-*-coding=utf-8-*- for a in range(1,50,1): for b in range(1,50,1): for c in range(1,50,1): if a+b+c ...
- php基础06:运算符
<?php //1.PHP 字符串运算符: 串接 $str1 = "gao"; $str1 = $str1."xiong"; echo $str1; ec ...
- System类及其常用函数
System 类包含一些有用的类字段和方法.它不能被实例化. 常用方法: 1.static void arraycopy(Object src, int srcPos, Object dest, in ...
- [CareerCup] 7.4 Implement Multiply Subtract and Divide 实现乘法减法和除法
7.4 Write methods to implement the multiply, subtract, and divide operations for integers. Use only ...