JAVA实现P2P内网穿透踩过的坑

p2p技术,又称为点对点(peer-to-peer),可以直接跨越NAT实现内网主机直接通讯。实现方式包括:中继(Relaying),逆向链接(Connection reversal), udp打洞(UDP hole punching)。中继方式是比较传统且效率较低的一种,不推荐使用,本人采用的是udp打洞,可以极大的降低服务器的压力,提高作业效率。
因为项目需要,开始研究起了p2p,之前对网络这块基本还是小白状态,首先,实现内网穿透,我们需要三台机器来搭建环境,一台处在内网的主机A,一台处在内网的主机B,一台处在公网的机器C。代码可参考:
代码转载自p2p代码实现,为了方便,我也把人家代码写在下面了。

注意点:

环境部分的影响因素:
1:部署位置。我们需要将服务端部署在公网环境中。
2:客户端与服务端的防火墙必须都处于关闭状态。
3:客户端与服务端的通信协议必须保持一致(ipv4与ipv6)。
4:保证网络稳定。
代码部分的影响因素:
1:内网主机穿透时必须是异步发起连接。
2:在穿透时,新建的连接,需要先设置SO_REUSEADDR,再绑定端口,最后进行连接,顺序不能错。
3:客户端获取本地ip地址时候,不能使用程序提供的封装方法:InetAddress.getLocalHost().getHostAddress(),需要手动设置改成实际的IP地址,因为有的机器可能有多个网卡或虚拟网卡,不该成当前实际的IP会导致使用错误的IP地址。(最重要的一点,深坑,这点会导致打洞失败!!!)

服务器端代码

package org.inchain.p2p;
 
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
 
/**
 * 外网端服务,穿透中继
 * 
 * @author ln
 *
 */
public class Server {
 
	public static List<ServerThread> connections = new ArrayList<ServerThread>();
 
	public static void main(String[] args) {
		try {
			// 1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
			ServerSocket serverSocket = new ServerSocket(8888);
			Socket socket = null;
			// 记录客户端的数量
			int count = 0;
			System.out.println("***服务器即将启动,等待客户端的连接***");
			// 循环监听等待客户端的连接
			while (true) {
				// 调用accept()方法开始监听,等待客户端的连接
				socket = serverSocket.accept();
				// 创建一个新的线程
				ServerThread serverThread = new ServerThread(socket);
				// 启动线程
				serverThread.start();
 
				connections.add(serverThread);
 
				count++;// 统计客户端的数量
				System.out.println("客户端的数量:" + count);
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

                
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值