基本信息
源码名称:基于ToyVpn的使用开发
源码大小:31.74M
文件格式:.zip
开发语言:Java
更新时间:2018-07-19
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
基于Android官方例子ToyVpn进行的VPN开发
VPN开发,sdk25版本,ndk15版本,vpn开发太难找了做参考吧,用官方给的文件自己搭建的VPN服务器,服务器是我领的免费阿里云,2018/7/31到期
package com.example.pc.service;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.net.VpnService;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.widget.Toast;
import com.example.pc.Activity.R;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
public class ToyVpnService extends VpnService implements Handler.Callback, Runnable {
private static final String TAG = "ToyVpnService";
private String mServerAddress;
private String mServerPort;
private byte[] mSharedSecret;
private PendingIntent mConfigureIntent;
private Handler mHandler;
private Thread mThread;
private ParcelFileDescriptor mInterface;
private String mParameters;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (mHandler == null) {
mHandler = new Handler(this);
}
if (mThread != null) {
mThread.interrupt();
}
String prefix = getPackageName();
mServerAddress = intent.getStringExtra(prefix ".ADDRESS");
mServerPort = intent.getStringExtra(prefix ".PORT");
mSharedSecret = intent.getStringExtra(prefix ".SECRET").getBytes();
mThread = new Thread(this, "ToyVpnThread");
mThread.start();
return START_STICKY;
}
@Override
public void onDestroy() {
if (mThread != null) {
mThread.interrupt();
}
}
@Override
public boolean handleMessage(Message message) {
if (message != null) {
Toast.makeText(this, message.what, Toast.LENGTH_SHORT).show();
}
return true;
}
@Override
public synchronized void run() {
try {
Log.i(TAG, "Starting");
InetSocketAddress server = new InetSocketAddress(
mServerAddress, Integer.parseInt(mServerPort));
for (int attempt = 0; attempt < 10; attempt) {
mHandler.sendEmptyMessage(R.string.connecting);
if (run(server)) {
attempt = 0;
}
Thread.sleep(3000);
}
Log.i(TAG, "Giving up");
} catch (Exception e) {
Log.e(TAG, "Got " e.toString());
} finally {
try {
mInterface.close();
} catch (Exception e) {
}
mInterface = null;
mParameters = null;
mHandler.sendEmptyMessage(R.string.disconnected);
Log.i(TAG, "Exiting");
}
}
private boolean run(InetSocketAddress server) throws Exception {
DatagramChannel tunnel = null;
boolean connected = false;
try {
tunnel = DatagramChannel.open();
if (!protect(tunnel.socket())) {
throw new IllegalStateException("Cannot protect the tunnel");
}
tunnel.connect(server);
tunnel.configureBlocking(false);
handshake(tunnel);
connected = true;
mHandler.sendEmptyMessage(R.string.connected);
FileInputStream in = new FileInputStream(mInterface.getFileDescriptor());
FileOutputStream out = new FileOutputStream(mInterface.getFileDescriptor());
ByteBuffer packet = ByteBuffer.allocate(32767);
int timer = 0;
while (true) {
boolean idle = true;
int length = in.read(packet.array());
if (length > 0) {
packet.limit(length);
tunnel.write(packet);
packet.clear();
idle = false;
if (timer < 1) {
timer = 1;
}
}
length = tunnel.read(packet);
if (length > 0) {
if (packet.get(0) != 0) {
out.write(packet.array(), 0, length);
}
packet.clear();
idle = false;
if (timer > 0) {
timer = 0;
}
}
if (idle) {
Thread.sleep(100);
timer = (timer > 0) ? 100 : -100;
if (timer < -15000) {
packet.put((byte) 0).limit(1);
for (int i = 0; i < 3; i) {
packet.position(0);
tunnel.write(packet);
}
packet.clear();
timer = 1;
}
if (timer > 20000) {
throw new IllegalStateException("Timed out");
}
}
}
} catch (InterruptedException e) {
throw e;
} catch (Exception e) {
Log.e(TAG, "Got " e.toString());
} finally {
try {
tunnel.close();
} catch (Exception e) {
// ignore
}
}
return connected;
}
private void handshake(DatagramChannel tunnel) throws Exception {
ByteBuffer packet = ByteBuffer.allocate(1024);
packet.put((byte) 0).put(mSharedSecret).flip();
for (int i = 0; i < 3; i) {
packet.position(0);
tunnel.write(packet);
}
packet.clear();
for (int i = 0; i < 50; i) {
Thread.sleep(100);
int length = tunnel.read(packet);
if (length > 0 && packet.get(0) == 0) {
configure(new String(packet.array(), 1, length - 1).trim());
return;
}
}
throw new IllegalStateException("Timed out");
}
private void configure(String parameters) throws Exception {
// If the old interface has exactly the same parameters, use it!
if (mInterface != null && parameters.equals(mParameters)) {
Log.i(TAG, "Using the previous interface");
return;
}
Builder builder = new Builder();
for (String parameter : parameters.split(" ")) {
String[] fields = parameter.split(",");
try {
switch (fields[0].charAt(0)) {
case 'm':
builder.setMtu(Short.parseShort(fields[1]));
break;
case 'a':
builder.addAddress(fields[1], Integer.parseInt(fields[2]));
break;
case 'r':
builder.addRoute(fields[1], Integer.parseInt(fields[2]));
break;
case 'd':
builder.addDnsServer(fields[1]);
break;
case 's':
builder.addSearchDomain(fields[1]);
break;
}
} catch (Exception e) {
throw new IllegalArgumentException("Bad parameter: " parameter);
}
}
try {
mInterface.close();
} catch (Exception e) {
// ignore
}
mInterface = builder.setSession(mServerAddress)
.setConfigureIntent(mConfigureIntent)
.establish();
mParameters = parameters;
Log.i(TAG, "New interface: " parameters);
}
}