还差实现内网终端,向服务器发送请求,要对方的内网连接自己,实现打洞。在同一网段,或者公网运行,可以相互聊天。

没有实现检测客户端下线功能。

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 内网穿透 互发消息的更多相关文章

  1. udp内网穿透 两个内网互联

    1,在有外网ip的机器上启动server. package udp; import java.net.DatagramPacket; import java.net.InetSocketAddress ...

  2. UDP 内网穿透 心跳

    参考:http://blog.csdn.net/jacman/article/details/ 1: 启动一个Server. 2: 启动两个Client. 然后从Server端的Console里边可以 ...

  3. 内网穿透&UDP打洞

    这两天找度度重新回忆了一下关于内网穿透的事情,在百度文库上找到了两三篇写的比较通俗易懂的文章,把内网穿透做个简单总结. 首先文章建议 Cone NAPT 还有希望,要是 Symmetri NAPT 就 ...

  4. 手写内网穿透服务端客户端(NAT穿透)原理及实现

    Hello,I'm Shendi. 这天心血来潮,决定做一个内网穿透的软件. 用过花生壳等软件的就知道内网穿透是个啥,干嘛用的了. 我们如果有服务器(比如tomcat),实际上我们在电脑上开启了服务器 ...

  5. 基于C#的内网穿透学习笔记(附源码)

    如何让两台处在不同内网的主机直接互连?你需要内网穿透!          上图是一个非完整版内外网通讯图由内网端先发起,内网设备192.168.1.2:6677发送数据到外网时候必须经过nat会转换成 ...

  6. 使用FRP做内网穿透

    Github地址:https://github.com/fatedier/frp 什么是FRP? frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp 协议,为 http 和 h ...

  7. 一款带Web面板的轻量级、高性能内网穿透工具:nps使用教程

    说明:内网穿透工具之前已经介绍了不少了,比如Frp.lanproxy.Holer等,现在再介绍个带Web面板的穿透工具nps,之前叫easyProxy,只是改名了而已,该工具是一款使用go语言编写的轻 ...

  8. frp内网穿透学习

    前言 因为自己在内网,但是目标站在外网,这时候可以通过内网穿透工具,将接收到的请求转发到内网,实现在内网的msf可以控制外网的靶机. 也看了一些Ngrok,花生壳的,发现Ngrok.cc这个看文章说有 ...

  9. 如何使用 frp 实现内网穿透

    这有一个专注Gopher技术成长的开源项目「go home」 背景 作为一名程序员,家里多多少少会有一些落了灰的电脑,如果把闲置的电脑变成服务器,不仅有良好的配置,还能用来做各种测试,那就再好不过了. ...

随机推荐

  1. C# 小型资源管理器

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  2. 图像相似度算法的C#实现及测评

    近日逛博客的时候偶然发现了一个有关图片相似度的Python算法实现.想着很有意思便搬到C#上来了,给大家看看. 闲言碎语 才疏学浅,只把计算图像相似度的一个基本算法的基本实现方式给罗列了出来,以至于在 ...

  3. python中class 的一行式构造器

    好处:避免类初始化时大量重复的赋值语句 用到了魔法__dict__ # 一行式构造器 class Test(): # 初始化 def __init__(self, a, b, c=2, d=3, e= ...

  4. 面试准备(二) 绘制 Activity 的生命流程图

    我们来看一下这一张经典的生命周期流程图: 相信不少朋友也已经看过这个流程图了,也基本了解了Activity生命周期的几个过程,我们就来说一说这几个过程. 1.启动Activity:系统会先调用onCr ...

  5. WebSocket使用教程 2

    WebSocket使用教程 - 带完整实例 收藏 james_laughing 发表于 2年前 阅读 46438 收藏 23 点赞 5 评论 4 摘要: WebSocket使用教程 - 带完整实例 什 ...

  6. Matlab中reshape函数的使用

    reshape把指定的矩阵改变形状,但是元素个数不变, 例如,行向量: a = [1 2 3 4 5 6] 执行下面语句把它变成3行2列: b = reshape(a,3,2) 执行结果: b = 1 ...

  7. livewriter写Blog 神秘失踪?

    现在习惯用livewriter来总结/记录一些知识并发布为Blog 与同行交流,但是今天发生了一个怪事,上午我整理了两篇文档当时就用livewriter发送到了Blog上,但是晚上来看的时候之前发送的 ...

  8. JAVA NIO是什么(zz)

    JAVA NIO是什么? 1.   基本 概念 IO 是主存和外部设备 ( 硬盘.终端和网络等 ) 拷贝数据的过程. IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成. 所有语言运行时系 ...

  9. app:发布新版本的具体步骤

    1

  10. openssl实践总结

    openssl实验总结 OPENSSL简介 OpenSSL项目是一个协作开发一个健壮的,商业级的,全功能的,并且开放源代码工具包,它实现了安全套接字层(SSL v2/v3)和传输层安全(TLS v1) ...