UPNP端口映射Android实现

这一段一直研究UPNP协议,搞得头都快炸了,找到一个upnp的jar包,感觉对发现InternetGatewayDevice非常方便。下面写了一个小程序,是发现路由器并进行端口映射的。


package com.example.laozhou.upnptest;

import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;


import net.sbbi.upnp.impls.InternetGatewayDevice;
import net.sbbi.upnp.messages.ActionResponse;
import net.sbbi.upnp.messages.UPNPResponseException;

import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.Locale;

public class Main2Activity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        new Thread(discoverUPNP).start();
    }

    Runnable discoverUPNP = new Runnable() {

        @Override
        public void run() {
            int discoveryTiemout = 5000; // 5 secs
            try {
                System.out.println("Looking for Internet Gateway Device...");
                InternetGatewayDevice[] IGDs = InternetGatewayDevice.getDevices(discoveryTiemout);
                if (IGDs != null) {
                    for (int i = 0; i < IGDs.length; i++) {
                        InternetGatewayDevice testIGD = IGDs[i];
                        System.out.println("\t\nFound device " + testIGD.getIGDRootDevice().getModelName());
                        System.out.println("External IP address: " + testIGD.getExternalIPAddress());

                        // now let's open the port
                        int portNum = 12345;
                        System.out.println("\nTrying to map dummy port " + portNum + "...");
//                        String localHostIP = getIpAddress();
                        String localHostIP = "192.168.2.201";
                        System.out.println("localHostIP " + localHostIP);
                        boolean mapped = testIGD.addPortMapping("chinavideo mapping", null, portNum, portNum, localHostIP, 0, "TCP");
                        System.out.println("AddPortState: " + mapped);
                        if (mapped) {
                            System.out.println("Port " + portNum + " mapped to " + localHostIP);
                            System.out.println("Current mappings count is " + testIGD.getNatMappingsCount());
                            // checking on the device
                            ActionResponse resp = testIGD.getSpecificPortMappingEntry(null, portNum, "TCP");
                            if (resp != null) {
                                System.out.println("Port " + portNum + " mapping confirmation received from device");
                            }
                        }
                    }
                    System.out.println("\nDone.");
                } else {
                    System.out.println("Unable to find IGD on your network");
                }
            } catch (IOException ex) {
                System.err.println("IOException occured during discovery or ports mapping " + ex.getMessage());
            } catch (UPNPResponseException respEx) {
                System.err.println("UPNP device unhappy " + respEx.getDetailErrorCode() + " " + respEx.getDetailErrorDescription());
            }

        }
    };

    private String getIpAddress() {
        WifiManager wifiManager = (WifiManager) Main2Activity.this.getSystemService(WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        int ipAddress = wifiInfo.getIpAddress();

        String ipaddress = String.format("%d.%d.%d.%d",
                (ipAddress & 0xff), (ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff),
                (ipAddress >> 24 & 0xff));
        return ipaddress;
    }

    public String getLocalIpAddress(){
        try {
            for (Enumeration en = NetworkInterface.getNetworkInterfaces();
                 en.hasMoreElements();) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress()) {
                        Log.d("ipAddress:",inetAddress.getHostAddress().toString());
                        return inetAddress.getHostAddress().toString();
                    }
                }
            }
        } catch (Exception ex) {
            Log.e("IP Address", ex.toString());
        }
        return null;
    }
}

其中端口号可以自己定义,因为我本机没有可测试接口,所以映射了局域网内一台机器的的接口到路由器。

所用包为 upnplib-mobile.jar

 
 

你可能感兴趣的:(程序,我的IT菜鸟之旅)