首页

基于ToyVpn的使用开发

java

2020-6-29

基于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);
    }
}  
资源下载此资源下载价格为4D币(VIP免费),请先
资源文件列表
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条信息!
没有账号? 忘记密码?

社交账号快速登录