还差实现内网终端,向服务器发送请求,要对方的内网连接自己,实现打洞。在同一网段,或者公网运行,可以相互聊天。
没有实现检测客户端下线功能。
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」 背景 作为一名程序员,家里多多少少会有一些落了灰的电脑,如果把闲置的电脑变成服务器,不仅有良好的配置,还能用来做各种测试,那就再好不过了. ...
随机推荐
-
4. Java Script 变量(untype)
没有块级作用域 数据类型 JavaScript中有5种简单数据类型(也称为基本数据类型):Undefined.Null.Boolean.Number和String.还有1种复杂数据类型——Object ...
-
网页引导:jQuery插件实现的页面功能介绍引导页效果
现在很多网站不仅是介绍,更多的是有一些功能,怎么样让客户快速的知道网站有哪些功能呢?这里pagewalkthrough.js插件能帮我们实现,它是一个轻量级的jQuery插件,它可以帮助我们创建一个遮 ...
-
WPF中多个RadioButton绑定到一个属性
如图样: 在View中: <RadioButton IsChecked="{Binding Option, Converter={cvt:EnumToBooleanConverter} ...
-
如何更改magento后台地址
magento默认的后台登陆地址是http://yourdomain.com/admin. 更改后台登陆地址是不难的,先用FTP登陆服务器,进入网站根目录,编辑app/etc/local.xml文件, ...
-
CE_现金银行总行分行设定详解(案例)
2014-07-14 Created By BaoXinjian
-
Entity Framework 6.1-Model First
原文:Entity Framework 6.1-Model First Model First-顾名思义,就是先创建EF数据模型,通过数据模型生成数据库的EF创建方式. 步骤. 1.新建一个DAL的文 ...
-
docker镜像与容器概念
本文用图文并茂的方式介绍了容器.镜像的区别和Docker每个命令后面的技术细节,能够很好的帮助读者深入理解Docker. 这篇文章希望能够帮助读者深入理解Docker的命令,还有容器(containe ...
-
python爬虫从入门到放弃(五)之 正则的基本使用
什么是正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是 事先定义好的一些特定字符.及这些特定字符的组合,组成一个"规则字符",这个"规则字符" 来表达对 ...
-
长图的展开与收起(Android)
前言: 在app的文章中,经常会夹杂着一些特别长的长图.在阅读的时候需要滑动很久才能看图片下方的文字,因此对于长图只展示图片上面一部分,并且可以展开这个功能是很重要的. 效果: 基本思路: 利用sca ...
-
SpringMVC+Apache Shiro+JPA(hibernate)案例教学(二)基于SpringMVC+Shiro的用户登录权限验证
序: 在上一篇中,咱们已经对于项目已经做了基本的配置,这一篇文章开始学习Shiro如何对登录进行验证. 教学: 一.Shiro配置的简要说明. 有心人可能注意到了,在上一章的applicationCo ...