基于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);
}
}
资源文件列表
MyApplication1/.gitignore , 127
MyApplication1/.gradle/3.3/taskArtifacts/fileHashes.bin , 157333
MyApplication1/.gradle/3.3/taskArtifacts/fileSnapshots.bin , 5841116
MyApplication1/.gradle/3.3/taskArtifacts/taskArtifacts.bin , 128885
MyApplication1/.gradle/3.3/taskArtifacts/taskArtifacts.lock , 17
MyApplication1/.gradle/3.3/tasks/_app_compileDebugJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.bin , 105592
MyApplication1/.gradle/3.3/tasks/_app_compileDebugJavaWithJavac/localClassSetAnalysis/localClassSetAnalysis.lock , 17
MyApplication1/.gradle/3.3/tasks/_app_compileDebugJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.bin , 21585
MyApplication1/.gradle/3.3/tasks/_app_compileDebugJavaWithJavac/localJarClasspathSnapshot/localJarClasspathSnapshot.lock , 17
MyApplication1/.idea/compiler.xml , 686
MyApplication1/.idea/copyright/profiles_settings.xml , 76
MyApplication1/.idea/gradle.xml , 626
MyApplication1/.idea/libraries/android_gif_drawable_1_2_6.xml , 632
MyApplication1/.idea/libraries/animated_vector_drawable_25_3_1.xml , 600
MyApplication1/.idea/libraries/appcompat_v7_25_3_1.xml , 564
MyApplication1/.idea/libraries/constraint_layout_1_0_0_alpha7.xml , 417
MyApplication1/.idea/libraries/constraint_layout_solver_1_0_0_alpha7.xml , 357
MyApplication1/.idea/libraries/espresso_core_2_2_2.xml , 578
MyApplication1/.idea/libraries/espresso_idling_resource_2_2_2.xml , 611
MyApplication1/.idea/libraries/exposed_instrumentation_api_publish_0_5.xml , 629
MyApplication1/.idea/libraries/hamcrest_core_1_3.xml , 526
MyApplication1/.idea/libraries/hamcrest_integration_1_3.xml , 354
MyApplication1/.idea/libraries/hamcrest_library_1_3.xml , 342
MyApplication1/.idea/libraries/javawriter_2_1_1.xml , 330
MyApplication1/.idea/libraries/javax_annotation_api_1_2.xml , 358
MyApplication1/.idea/libraries/javax_inject_1.xml , 324
MyApplication1/.idea/libraries/jsr305_2_0_1.xml , 330
MyApplication1/.idea/libraries/junit_4_12.xml , 477
MyApplication1/.idea/libraries/rules_0_5.xml , 539
MyApplication1/.idea/libraries/runner_0_5.xml , 542
MyApplication1/.idea/libraries/support_annotations_25_3_1.xml , 493
MyApplication1/.idea/libraries/support_compat_25_3_1.xml , 570
MyApplication1/.idea/libraries/support_core_ui_25_3_1.xml , 573
MyApplication1/.idea/libraries/support_core_utils_25_3_1.xml , 582
MyApplication1/.idea/libraries/support_fragment_25_3_1.xml , 576
MyApplication1/.idea/libraries/support_media_compat_25_3_1.xml , 588
MyApplication1/.idea/libraries/support_v4_25_3_1.xml , 404
MyApplication1/.idea/libraries/support_vector_drawable_25_3_1.xml , 597
MyApplication1/.idea/misc.xml , 2226
MyApplication1/.idea/modules.xml , 365
MyApplication1/.idea/runConfigurations.xml , 564
MyApplication1/.idea/workspace.xml , 193860
MyApplication1/app/.gitignore , 8
MyApplication1/app/app.iml , 10988
MyApplication1/app/build.gradle , 1131
MyApplication1/app/build/generated/source/buildConfig/androidTest/debug/com/example/pc/myapplication1/test/BuildConfig.java , 475
MyApplication1/app/build/generated/source/buildConfig/debug/com/example/pc/Activity/BuildConfig.java , 459
MyApplication1/app/build/generated/source/r/androidTest/debug/android/app/R.java , 241
MyApplication1/app/build/generated/source/r/androidTest/debug/android/support/test/espresso/idling/R.java , 266
MyApplication1/app/build/generated/source/r/androidTest/debug/android/support/test/espresso/R.java , 362
MyApplication1/app/build/generated/source/r/androidTest/debug/android/support/test/R.java , 250
MyApplication1/app/build/generated/source/r/androidTest/debug/android/support/test/rule/R.java , 358
MyApplication1/app/build/generated/source/r/androidTest/debug/com/example/pc/myapplication1/test/R.java , 409
MyApplication1/app/build/generated/source/r/debug/android/support/compat/R.java , 252
MyApplication1/app/build/generated/source/r/debug/android/support/constraint/R.java , 5539
MyApplication1/app/build/generated/source/r/debug/android/support/coreui/R.java , 252
MyApplication1/app/build/generated/source/r/debug/android/support/coreutils/R.java , 255
MyApplication1/app/build/generated/source/r/debug/android/support/fragment/R.java , 254
MyApplication1/app/build/generated/source/r/debug/android/support/graphics/drawable/animated/R.java , 272
MyApplication1/app/build/generated/source/r/debug/android/support/graphics/drawable/R.java , 263
MyApplication1/app/build/generated/source/r/debug/android/support/mediacompat/R.java , 257
MyApplication1/app/build/generated/source/r/debug/android/support/v4/R.java , 248
MyApplication1/app/build/generated/source/r/debug/android/support/v7/appcompat/R.java , 110550
MyApplication1/app/build/generated/source/r/debug/com/example/pc/Activity/R.java , 488377
MyApplication1/app/build/generated/source/r/debug/pl/droidsonroids/gif/R.java , 851
MyApplication1/app/build/intermediates/blame/res/androidTest/debug/multi/values.json , 912
MyApplication1/app/build/intermediates/blame/res/debug/multi/color.json , 2
MyApplication1/app/build/intermediates/blame/res/debug/multi/drawable.json , 2
MyApplication1/app/build/intermediates/blame/res/debug/multi/layout-v16.json , 2
MyApplication1/app/build/intermediates/blame/res/debug/multi/layout.json , 2
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-af.json , 15351
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-am.json , 15345
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-ar.json , 15353
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-az-rAZ.json , 14794
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-b+sr+Latn.json , 15663
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-be-rBY.json , 15533
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-bg.json , 15357
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-bn-rBD.json , 15537
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-bs-rBA.json , 15533
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-ca.json , 15357
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-cs.json , 15353
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-da.json , 15349
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-de.json , 15353
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-el.json , 15359
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-en-rAU.json , 15525
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-en-rGB.json , 15525
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-en-rIN.json , 15525
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-es-rUS.json , 15535
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-es.json , 15355
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-et-rEE.json , 15535
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-eu-rES.json , 15531
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-fa.json , 15355
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-fi.json , 15349
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-fr-rCA.json , 15535
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-fr.json , 15359
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-gl-rES.json , 15533
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-gu-rIN.json , 15529
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-h720dp-v13.json , 945
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-hdpi-v4.json , 1005
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-hi.json , 15355
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-hr.json , 15353
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-hu.json , 15359
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-hy-rAM.json , 15527
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-in.json , 15355
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-is-rIS.json , 15523
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-it.json , 15351
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-iw.json , 15347
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-ja.json , 15341
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-ka-rGE.json , 15531
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-kk-rKZ.json , 15529
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-km-rKH.json , 15527
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-kn-rIN.json , 15533
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-ko.json , 15337
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-ky-rKG.json , 15529
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-land.json , 3084
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-large-v4.json , 6775
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-ldltr-v21.json , 943
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-lo-rLA.json , 15525
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-lt.json , 15359
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-lv.json , 15357
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-mk-rMK.json , 14065
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-ml-rIN.json , 15533
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-mn-rMN.json , 15527
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-mr-rIN.json , 15533
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-ms-rMY.json , 15531
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-my-rMM.json , 15535
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-nb.json , 15345
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-ne-rNP.json , 15537
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-night-v8.json , 5315
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-nl.json , 15359
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-pa-rIN.json , 15525
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-pl.json , 15355
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-port.json , 921
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-pt-rBR.json , 15535
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-pt-rPT.json , 15535
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-pt.json , 15359
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-ro.json , 15359
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-ru.json , 15357
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-si-rLK.json , 15531
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-sk.json , 15351
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-sl.json , 15355
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-sq-rAL.json , 15531
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-sr.json , 15355
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-sv.json , 15353
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-sw.json , 15351
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-sw600dp-v13.json , 6094
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-ta-rIN.json , 15533
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-te-rIN.json , 15535
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-th.json , 15351
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-tl.json , 15361
MyApplication1/app/build/intermediates/blame/res/debug/multi/values-tr.json , 15351
最多只能显示150条信息!
