在好例子网,分享、交流、成长!
您当前所在位置:首页Java 开发实例Android平台开发 → 基于ToyVpn的使用开发

基于ToyVpn的使用开发

Android平台开发

下载此实例
  • 开发语言:Java
  • 实例大小:31.74M
  • 下载次数:75
  • 浏览次数:2664
  • 发布时间:2018-07-19
  • 实例类别:Android平台开发
  • 发 布 人:sniper101
  • 文件格式:.zip
  • 所需积分:2
 相关标签: VPN ToyVpn Android

实例介绍

【实例简介】基于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);
    }
}  


标签: VPN ToyVpn Android

实例下载地址

基于ToyVpn的使用开发

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警