udp 内网穿透 互发消息
还差实现内网终端,向服务器发送请求,要对方的内网连接自己,实现打洞。在同一网段,或者公网运行,可以相互聊天。
没有实现检测客户端下线功能。
1,服务器代码
package router; import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.util.HashSet;
import java.util.Set; public class Server {
// private Set<InetSocketAddress> clients= new HashSet();
DatagramSocket socket;
HeartBeat heart; Server(){
try {
socket = new DatagramSocket(9090);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public void startServer(){
try { while(true){
byte[] buf = new byte[1024]; DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
InetAddress addr=packet.getAddress();
int port = packet.getPort(); InetSocketAddress address = new InetSocketAddress(addr,port);
heart.add(address);
send(heart.getDests(), address); String s = address + " is comming.";
notifyClients(s);
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
private void send(Object clients, SocketAddress client) throws IOException {
ByteArrayOutputStream bous = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bous);
oos.writeObject(clients);
oos.flush(); byte[] data= bous.toByteArray();
DatagramPacket sendip = new DatagramPacket(data, data.length);
sendip.setSocketAddress(client);
socket.send(sendip); } void notifyClients(String s){ for( SocketAddress client:heart.getDests()){
try {
send(s, client);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} public static void main(String[] args) {
Server server =new Server();
server.heart = new HeartBeat(server.socket);
server.startServer();
} }
2,客户端
package router; import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.util.Set; import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField; public class Client extends Thread {
String serverip = "211.100.75.221";//"192.168.11.100";//
private SocketAddress server = new InetSocketAddress(serverip, 9090);
DatagramSocket socket; JTextArea jta_receive = new JTextArea(10, 50); JComboBox jta_addList = new JComboBox(); public Client() {
try {
socket = new DatagramSocket();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public void run() {
try { while (true) {
byte[] buf = new byte[1024]; DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
// log(new String(buf,buf.length));
read(packet.getData());
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } private void read(byte[] data) throws IOException, ClassNotFoundException {
ByteArrayInputStream bous = new ByteArrayInputStream(data);
ObjectInputStream oos = new ObjectInputStream(bous);
Object obj = oos.readObject(); if (obj instanceof Set) {
Set<InetSocketAddress> clients = (Set) obj;
jta_addList.removeAll();
jta_addList.removeAllItems(); for (InetSocketAddress it : clients) {
log(" add item:"+ it);
jta_addList.addItem(it);
}
}else if(obj instanceof String){
String ss =(String) obj;
if(!ss.startsWith("skip")){
jta_receive.append(ss);
jta_receive.append("\r\n");
}
}
}
void log(String s){
System.out.println(s);
}
void setUpUI() {
JFrame jf = new JFrame("p2p test");
jf.setLayout(new FlowLayout());
jf.setSize(700, 400); JButton jb_get = new JButton("get others ip");
jf.add(jb_get);
jf.add(jta_addList);
jb_get.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
sendRequestMsg("getaddress"); } }); JLabel la_name = new JLabel("received:");
JLabel la_user = new JLabel("sendto:"); final JTextField jtf_send = new JTextField(20);
JButton bu_send = new JButton("send"); JScrollPane js = new JScrollPane(jta_receive); jf.add(la_name);
jf.add(js);
jf.add(la_user);
jf.add(jtf_send);
jf.add(bu_send); ActionListener sendListener = new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
String msg = jtf_send.getText();
InetSocketAddress dest = (InetSocketAddress) jta_addList
.getSelectedItem();
sendP2P(msg, dest);
jtf_send.setText("");
} }; bu_send.addActionListener(sendListener);
jtf_send.addActionListener(sendListener); jf.setVisible(true);
jf.setDefaultCloseOperation(3); } private void sendRequestMsg(String s) {
try {
byte[] buf = s.getBytes();
DatagramPacket packet; packet = new DatagramPacket(buf, buf.length, server); socket.send(packet); } catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} private void sendP2P(String msg, InetSocketAddress dest) {
try {
ByteArrayOutputStream bous = new ByteArrayOutputStream();
ObjectOutputStream oos;
oos = new ObjectOutputStream(bous); oos.writeObject(msg);
oos.flush(); byte[] data = bous.toByteArray();
DatagramPacket sendip = new DatagramPacket(data, data.length);
sendip.setSocketAddress(dest);
socket.send(sendip);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public static void main(String[] args) {
Client sender = new Client();
sender.start();
sender.setUpUI(); } }
3,心跳类
package router; import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask; public class HeartBeat {
private static final long INTERVAL_TIME = 1 * 5 * 1000; private Timer timer;
static Set<SocketAddress> dests = new HashSet();
DatagramSocket socket;
public HeartBeat(DatagramSocket socket) {
this.socket = socket; 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() {
Set<SocketAddress> tmpDests = new HashSet<SocketAddress>();
byte[] b = "skip".getBytes(); // 发送心跳
println("====heartbeat====");
for (SocketAddress dest : dests) { println(dest.toString());
sendP2P("skip", dest);
// DatagramPacket packet = new DatagramPacket(b, b.length);
// packet.setSocketAddress(dest);
// socket.send(packet);
tmpDests.add(dest); }
dests = tmpDests;
}
} private void sendP2P(String msg, SocketAddress dest) {
try {
ByteArrayOutputStream bous = new ByteArrayOutputStream();
ObjectOutputStream oos;
oos = new ObjectOutputStream(bous); oos.writeObject(msg);
oos.flush(); byte[] data = bous.toByteArray();
DatagramPacket sendip = new DatagramPacket(data, data.length);
sendip.setSocketAddress(dest);
socket.send(sendip);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public void add(SocketAddress a){
dests.add(a);
}
public Set<SocketAddress> getDests() {
return dests;
} public void setDests(Set<SocketAddress> dests) {
this.dests = dests;
} SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd H:m:s"); public void println(String s) {
System.out.println(format.format(new Date()) + ": " + s);
}
}
udp 内网穿透 互发消息的更多相关文章
- udp内网穿透 两个内网互联
1,在有外网ip的机器上启动server. package udp; import java.net.DatagramPacket; import java.net.InetSocketAddress ...
- UDP 内网穿透 心跳
参考:http://blog.csdn.net/jacman/article/details/ 1: 启动一个Server. 2: 启动两个Client. 然后从Server端的Console里边可以 ...
- 内网穿透&UDP打洞
这两天找度度重新回忆了一下关于内网穿透的事情,在百度文库上找到了两三篇写的比较通俗易懂的文章,把内网穿透做个简单总结. 首先文章建议 Cone NAPT 还有希望,要是 Symmetri NAPT 就 ...
- 手写内网穿透服务端客户端(NAT穿透)原理及实现
Hello,I'm Shendi. 这天心血来潮,决定做一个内网穿透的软件. 用过花生壳等软件的就知道内网穿透是个啥,干嘛用的了. 我们如果有服务器(比如tomcat),实际上我们在电脑上开启了服务器 ...
- 基于C#的内网穿透学习笔记(附源码)
如何让两台处在不同内网的主机直接互连?你需要内网穿透! 上图是一个非完整版内外网通讯图由内网端先发起,内网设备192.168.1.2:6677发送数据到外网时候必须经过nat会转换成 ...
- 使用FRP做内网穿透
Github地址:https://github.com/fatedier/frp 什么是FRP? frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp 协议,为 http 和 h ...
- 一款带Web面板的轻量级、高性能内网穿透工具:nps使用教程
说明:内网穿透工具之前已经介绍了不少了,比如Frp.lanproxy.Holer等,现在再介绍个带Web面板的穿透工具nps,之前叫easyProxy,只是改名了而已,该工具是一款使用go语言编写的轻 ...
- frp内网穿透学习
前言 因为自己在内网,但是目标站在外网,这时候可以通过内网穿透工具,将接收到的请求转发到内网,实现在内网的msf可以控制外网的靶机. 也看了一些Ngrok,花生壳的,发现Ngrok.cc这个看文章说有 ...
- 如何使用 frp 实现内网穿透
这有一个专注Gopher技术成长的开源项目「go home」 背景 作为一名程序员,家里多多少少会有一些落了灰的电脑,如果把闲置的电脑变成服务器,不仅有良好的配置,还能用来做各种测试,那就再好不过了. ...
随机推荐
- sqlzoo.net刷题5
List the continents that have a total population of at least 100 million. 这题考察的是使用集聚函数生成表之后,如何过滤 一般我 ...
- cotangent Laplacian
几何网格处理经常用到 cotangent laplacian矩阵.前几天把这个功能整合到我的Maya 转 Matlab插件了. 这里发一个利用cotangent laplacian计算特征向量并显示的 ...
- “display:block-inline形式的Span或Div中添加文字后,导致Span或Div排版掉落、错位”的原因及解决方法
最近在使用3个span(或div)制作带圆角边框的按钮时,按照常识,把span的display设置成inline-block,这样就可以设置span的width和height了,很爽的~ 可是当我在中 ...
- 整理MAC下Eclipse的常用快捷键
整理Eclipse常用快捷键 开发环境切换到Mac下后原来Window下的快捷键很大一部分是不相容的,习惯了快捷键的生活忽然哪天快捷键不起作用了,跟着的就是开发效率明显降低,频繁录入错误的快捷键让Ec ...
- 【转】【C#】SendMessage
SendMessage是一个在user32.dll中声明的API函数,在C#中导入如下: using System.Runtime.InteropServices; [DllImport(" ...
- 对RESTful Web API的理解与设计思路
距离上一篇关于Web API的文章(如何实现RESTful Web API的身份验证)有好些时间了,在那篇文章中提到的方法是非常简单而有效的,我在实际的项目中就这么用了,代码经过一段时间的磨合,已经很 ...
- GEOS库在windows中的编译和测试(vs2012)
版本:vs2012, geos3.5 一.下载和编译 这类的文章比较,不再具体细说,可以参考 http://blog.csdn.net/wangqinghao/article/details/8201 ...
- Linux基础入门学习笔记20135227黄晓妍
学习计时:共24小时 读书:1小时 代码:8小时 作业:3小时 博客:12小时 一.学习目标 1. 能够独立安装Linux操作系统 2. 能够熟练使用Linux系统的基本命令 3. 熟练使用L ...
- GDB堆栈跟踪与汇编调试
GDB堆栈跟踪与汇编调试 堆栈跟踪 源代码: 对预先编写的 stack.c 文件进行编译,并且使用 CGDB 进行调试,对堆栈进行跟踪,了解该代码堆栈是如何变化的. 在 CGDB 中,先设置 main ...
- 关于php析构函数的一个有趣问题
随着面向对象编程的普遍展开,面向对象展现了其中很多有趣的问题.相信很多初学者学习php面向对象时会接触两个函数,构造函数与析构函数.构造函数似乎用的更多,析构函数用的较少(相对初学者有限编程经验而言, ...