- 浏览: 282584 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (153)
- unix (2)
- sql (3)
- pl/sql (1)
- cvs (1)
- core java (36)
- OOAD UML (1)
- XML (4)
- JDBC (5)
- Hibernate (1)
- HTML (1)
- javascript (2)
- servlet (2)
- jsp (1)
- AJAX (1)
- Struts1.x (0)
- Struts2.x (5)
- Spring (6)
- EJB (2)
- WebService (2)
- 生活 (2)
- 感情 (0)
- 其他 (9)
- jbuilder2005 (1)
- db2 (1)
- groovy (1)
- 银行业务 (1)
- Android (9)
- java设计模式 (8)
- J2SE (2)
- DataBase (4)
- lucene (2)
- java卡 (1)
- flex (3)
- 烹饪 (1)
- 测试 (1)
- java硬件 (2)
- upnp (3)
- S2SH lib (1)
- nio CshBBrain (1)
- socket (1)
- 二维码 (1)
- 热加载 (1)
- hadoop (3)
- NIO (1)
- 新银行前置机预研 (1)
- springmvc3 (1)
- jvm (1)
- sf (0)
最新评论
-
niwowl:
可以!
gson使用在android使用例子 -
smallbee:
xin_jmail 写道首先感谢楼主的文章,让我知道了lock ...
java ReentrantLock Condition调试记录 -
xin_jmail:
首先感谢楼主的文章,让我知道了lock.newConditio ...
java ReentrantLock Condition调试记录 -
smallbee:
brad2309 写道lz 你的两个messageReceiv ...
基于Apache Mina实现的TCP长连接和短连接实例 -
brad2309:
lz 你的两个messageReceived方法是不是错乱了
基于Apache Mina实现的TCP长连接和短连接实例
我的上一篇日志是说明打洞原理http://smallbee.iteye.com/blog/1029835
下面来说说如何用java实现穿越。 感谢(你是我的谁? 83289331)提供代码
服务器端:
public class UDPServer extends UDPAgent { public static void main(String[] args) throws Exception { //开启2008服务器端口,接收客户端udp请求,同时也接收用户命令 new UDPServer(2008).start(); } public UDPServer(int port) { super(port); } }
客户端:
import java.net.DatagramPacket; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; public class UDPClient extends UDPAgent { public static void main(String[] args) throws Exception { new UDPClient("127.0.0.1", 2008, -1).start(); } private SocketAddress server; public UDPClient(String host, int port, int localPort) { super(localPort); this.server = new InetSocketAddress(host, port); } public void start() throws Exception { println("start"); init(); //构造客户端的 DatagramSocket register(); //向服务器发送字符串:register " + getLocalAddress() + " " + ds.getLocalPort() new Thread(this).start();//往自己输入的一个ip port发送东西 receive(); //循环接收服务器发来请求 打印出来 } public void onReceive(DatagramPacket rec) { try { report(rec); if (rec.getSocketAddress().equals(server)) { doCommand(new String(rec.getData(), rec.getOffset(), rec .getLength())); } } catch (Exception e) { e.printStackTrace(); } } public void report(DatagramPacket rec) throws Exception { String s = rec.getSocketAddress() + new String(rec.getData(), rec.getOffset(), rec.getLength()); byte[] buf = s.getBytes(); 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(); } }
共有父类:
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.regex.Pattern; 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); public static String ipPattern = "([0-9]{1,3}.){3}[0-9]{1,3}"; public static String portPattern = "[0-9]{1,5}"; public 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); } } public void start() throws Exception { println("start"); println("LocalPort:" + port); init(); //构造服务器udp socket new Thread(this).start();//往自己输入的一个ip port发送东西 receive(); //循环接收客户端发来请求 打印出来 } public void receive() { for (;;) { try { ds.receive(rec); String msg = new String(rec.getData(), rec.getOffset(), rec .getLength()); String line = 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()) { doSend(cmd); } } public void doSend(String cmd) throws Exception { println("CMD: " + cmd); String[] s = cmd.split(" ", 4); int port = Integer.parseInt(s[2]); InetSocketAddress target = new InetSocketAddress(s[1], port); byte[] bs = s[3].getBytes(); doSend(target, bs); } public void doSend(SocketAddress addr, byte[] data) throws Exception { 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(); } } public void println(String s) { System.out.println(System.currentTimeMillis() + ":" + s); } }
当服务器启动日志:
1304581809784:start
1304581809784:LocalPort:2008
启动一个客户端在客户端日志:
1304581880627:start
此时在服务器端日志:
1304581809784:start
1304581809784:LocalPort:2008
1304581880674:/127.0.0.1:2465:register 99.6.150.31 2465
再启动一个客户端日志:
1304581964923:start
此时服务器端日志:
1304581809784:start
1304581809784:LocalPort:2008
1304581880674:/127.0.0.1:2465:register 99.6.150.31 2465
1304581964939:/127.0.0.1:2469:register 99.6.150.31 2469
相当于两个客户端连接服务器的IP都为99.6.150.31 端口分别为 2465和2469
由于本人在自己机子上模拟多客户端,其实还是在一个局域网内。
然后控制台到客户端1(即端口为2465那个),输入 send 99.6.150.31 2469 我要连接2469
这个时候,在客户端2(2469端口)会看到如下:1304582321669:/99.6.150.31:2465:我要连接2469
如果按照穿越原理,这种情况应该是不可能的,因为在2465的网关没有记录客户端1的信息,应该会被抛弃。但是这个步骤必做不可,原因是这样做,能在客户端1的网关记录客户端2的信息,这样客户端2就可以向客户端1网关发起请求而不被抛弃(我是这么认为的)。
最后用客户端2发起一个请求给客户端1,这个时候,由于客户端1的网关已经有记录客户端2的信息,所以不会被抛弃,这样通信链路就连上了。
接下来,如果客户端1要往客户端2发送信息只要往 99.6.150.31 2469发送。客户端2往客户端1发送只要往99.6.150.31 2465发送即可。
以上推论需要环境测试,欢迎大家测试告之结果。
- Holl.rar (6.9 KB)
- 下载次数: 34
评论
发表评论
-
bike1
2015-12-07 17:10 0rt -
GPRS打印机的原理
2015-07-31 09:09 753一、什么是GPRS无线打印 ... -
关于 expression="execution(* com.xy.service.*.*(..))"
2015-05-21 09:22 2660先来看看这个spring的配 ... -
md5 sha1 java和javascript实现
2015-05-21 08:11 878<%@ page language="ja ... -
RSA帮助类
2014-11-21 09:36 925package com.cmb.fmserver.passp ... -
src2014-2-17
2014-02-17 21:55 0rt -
springmvc例子
2014-02-11 11:09 0rt -
qhdescjyw
2014-02-11 10:33 0rt -
按字节截取含有中文汉字的字符串
2013-05-07 18:55 3102要求实现一个按字节截取字符串的方法,比如对于字符串&quo ... -
SSL多线程安全问题
2013-04-23 15:44 1760项目原因,代码实现 ... -
wait notify 对象锁
2013-03-14 15:21 1162通常,多线程之间需要协调工作。例如,浏览器的一个显示图片的 ... -
eclipse下配置hadoop环境
2012-12-05 11:44 1415按照http://smallbee.iteye.com ... -
centos虚拟机上安装运行hadoop(伪分布)
2012-11-15 15:28 19601、先在确认能否不输入口令就用ssh登录localhost: ... -
nio 远程主机强迫关闭了一个现有的连接 解决方案
2012-10-17 12:37 4603nio编程过程中会出现: Exception in thre ... -
java nio过程
2012-10-17 11:32 12371、服务端:ServerSocketChannel进行监听,注 ... -
socket 客户端连接池实现
2012-10-15 16:58 6716本文参考:http://cache.baidu.com/c?m ... -
java dom 解析xml例子
2012-08-02 14:09 1558XML格式如下: <?xml version=&quo ... -
DM5 java 例子
2012-08-02 10:38 1247package com.cmb.fbcbcserver; ... -
HTTP短连接模拟长连接 连接数不能超过2个
2012-08-01 15:47 2029项目中有用到服务器推技术,也是由于环境因素,银行系统,行内机房 ... -
java注解使用例子
2012-07-30 11:50 11821、注解定义: import java.lang.annot ...
相关推荐
描述中的“TCP实现P2P通信、TCP穿越NAT的方法、TCP打洞(附源代码).doc”进一步确认了这个压缩包包含了一篇文档,详细介绍了如何通过TCP协议进行P2P通信,NAT穿越的技术以及TCP打洞的实践方法,并且提供了源代码。...
java源代码来说明tcp穿越NAT的原理。
TCP打洞分为两种主要类型:被动打洞和主动打洞。被动打洞依赖于服务器辅助,其中一个端点(称为客户端A)向公共服务器发送其内网NAT映射的IP和端口,然后服务器将这些信息转发给另一个端点(客户端B)。客户端B收到...
Netty UDP协议网络打洞实例是利用Netty框架在UDP(User Datagram Protocol)协议基础上实现的一种穿透NAT(Network Address Translation)的技术。NAT技术在现代互联网中广泛使用,它允许内部网络中的设备共享一个...
C# UDP穿越NAT打洞,可在广域网实现仿qq即时通讯,点对点发送消息。
UDP打洞测试程序,实现点对点信息传输,C#提供了Sockets来进行套接字的编程,里面包含了TcpClient和UdpClient。用过的大家都知道Tcp发送消息更安全,而Udp传送数据容易丢包,但速度快,能穿越防火墙。目前比较流行的...
### UDP穿越NAT与UDP打洞技术解析及C#实现 #### 一、UDP穿越NAT与UDP打洞概述 在网络通信中,由于NAT(Network Address Translation)的存在,两个位于不同私有网络中的主机之间很难直接进行UDP通信。为了克服这一...
本文档介绍了 UDP/TCP 打洞技术的实现原理和步骤,该技术用于穿越 NAT(Network Address Translation,网络地址转换),解决 P2P 通信领域中的 NAT 问题。该技术可以在 UDP 和 TCP 通信领域中应用,实现可靠的 P2P ...
《基于Java Swing的三国杀游戏实现详解》 在IT领域,游戏开发是一项充满挑战与创新的工作,而将经典桌面游戏“三国杀”移植到计算机上则更是考验开发者的技术实力和对游戏规则的理解。本项目“Sanguosha.rar”就是...
本篇文章将深入探讨如何利用TCP实现P2P通信,以及TCP穿越NAT的策略,特别是TCP打洞技术。 首先,TCP实现P2P通信的核心在于对等节点之间的连接建立。在P2P网络中,每个节点都有一个私有IP地址,可能被NAT设备隐藏。...
本文将详细探讨如何使用TCP实现P2P通信,以及TCP穿越NAT的方法,特别是TCP打洞技术,并提供相关的源代码参考。 首先,TCP实现P2P通信的关键在于建立可靠的端到端连接。在P2P网络中,每个节点都有一个私有IP地址,这...
"C#打洞demo"是一个示例项目,展示了如何使用C#编程语言实现P2P通信中的UDP打洞技术,以实现穿越路由器进行外网通信。 UDP(User Datagram Protocol)是传输层的一个无连接协议,它不保证数据的可靠传输,但具有低...
因为当前 IPV4地址的缺乏 ,nat、防火墙的中介设备和不对称寻址建立起来的 p2p通信机制造成了地址访问的问题。 在 internet最初体系结构中,每个节点都有全球唯一的 ip地址,能够...此时我们需要的就是穿越技术。。。
UDP穿越防火墙的例子,有助于学习UDP打洞原理哦。
标题中的"NET-P2P.rar_NET穿越_nat_p2p nat_传输模块类型"涉及了几个关键概念:NAT穿越、P2P通信以及不同类型的网络传输模块。下面将详细解释这些知识点。 首先,NAT(网络地址转换)是一种网络技术,用于在公共...
通过分析和理解这些源代码,开发者可以深入学习TCP打洞的工作原理,并将其应用到实际的P2P应用程序中,比如实现高质量的文件传输服务,确保数据的可靠传输,同时减少丢包情况。"www.pudn.com.txt"可能是文档来源或者...
而“UDP打洞源码及原理分析.rar”则可能更深入地讲解了UDP打洞的具体实现细节和背后的网络原理。通过学习这些资料,你可以更好地理解如何在实际项目中应用UDP打洞技术,解决内网通信问题。 需要注意的是,UDP打洞并...
【标题】"Nat.zip"指的是一个包含NAT(网络地址转换)相关程序的压缩文件,其后缀"_java"标明了这些程序是用Java编程语言编写的。"Nat"在计算机网络领域中是一个重要的概念,它允许有限的公网IP地址为多台内部设备...
Java实现HTTP PROXY是一个常见的需求,特别是在开发网络应用或者测试环境中,我们可能需要通过代理服务器转发HTTP请求。本文将深入探讨如何使用Java编程语言来创建一个HTTP代理服务器,并且会涉及相关的源码分析。 ...