Files
vnt/vnt-jni/java_example/AndroidVpnExample.java
T
2026-02-24 18:31:40 +08:00

145 lines
4.3 KiB
Java

import android.net.VpnService;
import android.os.ParcelFileDescriptor;
import com.vnt.*;
/**
* Android VPN服务示例
*
* 演示如何正确使用VNT JNI接口:
* 1. 创建网络
* 2. 注册获取IP/掩码
* 3. 用获取的参数建立Android VPN接口
* 4. 传入tunFd启动VNT
*/
public class AndroidVpnExample extends VpnService {
private VntNetwork network;
private ParcelFileDescriptor vpnInterface;
@Override
public int onStartCommand(android.content.Intent intent, int flags, int startId) {
try {
startVpn();
return START_STICKY;
} catch (Exception e) {
e.printStackTrace();
stopSelf();
return START_NOT_STICKY;
}
}
private void startVpn() throws Exception {
// 1. 初始化VNT(全局初始化,只需一次)
if (!VntManager.init()) {
throw new VntException("Failed to initialize VNT");
}
// 2. 构建配置
VntConfig config = new VntConfig.Builder()
.addServer("tcp://101.35.230.139:6660")
.setNetworkCode("your_network_code")
.setPassword("123456")
.setDeviceName("AndroidDevice")
.setCompress(true)
.setMtu(1380)
.build();
// 3. 创建网络实例
network = VntManager.createNetwork(config);
if (network == null) {
throw new VntException("Failed to create network");
}
// 4. 注册网络(连接服务器,获取分配的IP和掩码)
RegisterResult result = network.register();
System.out.println("Registration successful: " + result);
// 5. 使用注册返回的IP和掩码,建立Android VPN接口
VpnService.Builder builder = new Builder();
builder.setMtu(1380);
builder.addAddress(result.getIp(), result.getPrefixLen());
builder.addRoute("0.0.0.0", 0); // 全局路由
builder.setSession("VNT VPN");
// 建立VPN接口,获取文件描述符
vpnInterface = builder.establish();
if (vpnInterface == null) {
throw new VntException("Failed to establish VPN interface");
}
int tunFd = vpnInterface.getFd();
System.out.println("VPN interface established, fd: " + tunFd);
// 6. 将tunFd传给VNT,启动数据转发
network.startTun(tunFd);
System.out.println("VNT started successfully!");
// 7. 获取API用于查询状态
VntApi api = network.getApi();
// 8. 查询网络信息
VntApi.NetworkInfo networkInfo = api.getNetwork();
System.out.println("Network info: " + networkInfo);
// 9. 查询NAT信息
VntApi.NatInfo natInfo = api.getNatInfo();
System.out.println("NAT info: " + natInfo);
}
@Override
public void onDestroy() {
super.onDestroy();
// 清理资源
if (network != null) {
network.stop();
network = null;
}
if (vpnInterface != null) {
try {
vpnInterface.close();
} catch (Exception e) {
e.printStackTrace();
}
vpnInterface = null;
}
VntManager.destroy();
}
/**
* 查询客户端列表(可在UI线程定期调用)
*/
public void queryClients() {
if (network == null) {
return;
}
try {
VntApi api = network.getApi();
for (VntApi.ClientInfo client : api.getClientList()) {
System.out.println("Client: " + client);
// 检查是否直连
boolean direct = api.isDirect(client.getIp());
System.out.println(" Direct: " + direct);
// 获取丢包信息
VntApi.PacketLossInfo loss = api.getPacketLoss(client.getIp());
if (loss != null) {
System.out.println(" Packet loss: " + loss);
}
// 获取流量信息
VntApi.TrafficInfo traffic = api.getTrafficInfo(client.getIp());
if (traffic != null) {
System.out.println(" Traffic: " + traffic);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}