android如何判断两台设备在同一个局域网内

目录

  • android如何判断两台设备在同一个局域网内
      • 第一种方法,比较(ip与netMask)的值
      • 第二种方法,根据TTL跳数判定在不在同一个局域网

判断两台设备在不在同一个局域网内有两种方法:

第一种方法是:分别拿到两台设备的ip地址(int类型的ip)和子网掩码(int类型的netMask),然后得到两台设备 ip and netMask 的值,如果相同就是在同一个局域网内,否则就不是。
第二种方法是:通过ping命令,得到TTL跳数,如果TTL跳数不是32,64,128,255之一,代表不是在同一个局域网。

第一种方法,比较(ip与netMask)的值

这种方法主要是根据ip地址(ip)和和子网掩码(netMask)判断的。首先查询ip和netMask,android端代码如下:

var wifiManager = context..getSystemService(Context.WIFI_SERVICE) as WifiManagervar dhcpInfo = wifiManager.getDhcpInfo();var ipAddress = dhcpInfo.ipAddress;//ip地址,int类型的var gateway = dhcpInfo.gateway;//网关地址,int类型的var netmask = dhcpInfo.netmask;//子网掩码,int类型的然后比较两个设备的  ipAddress and netmask  与运算的值是不是相等

需要权限

第二种方法,根据TTL跳数判定在不在同一个局域网

这个方法主要是通过ping命令,来得到TTL跳数,根据TTL跳数来判断。每台设备上TTL都有一个初始值,一般是32,64(常见),128,255(常见)。如果两台设备在同一个局域网,那么TTL就是32、64、128、255这4个数中的一个;
反之如果两台设备不在同一个局域网内,中间有路由器转发,那么
ping命令,相信大家都很熟悉,这里就不多说了。如果不懂的可以百度,网上有很多这方面的资料。直接上代码:

fun isInSameLAN(ipAddress: String): Boolean {    var isInSameLAN = false    try {        val process = Runtime.getRuntime().exec("ping -c 1 -w 1 $ipAddress")        var returnMsg = LineNumberReader(InputStreamReader(process.inputStream)).use {            var sb = StringBuilder()            var readLine: String?            while (true) {                readLine = it.readLine() ?: break                sb.append(readLine)            }            sb.toString()        }        val splits = returnMsg.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()        for (i in splits.indices) {            val split = splits[i]            if (split.contains("ttl")) {                if (split.contains("32") || split.contains("64") || split.contains("128") || split.contains("255")) {                    isInSameLAN = true                }            }        }    } catch (e: IOException) {        e.printStackTrace()    }    return isInSameLAN }

android如何判断两台设备在同一个局域网内_第1张图片
代买如下:

package jaydenxiao.com.sameintranetimport android.content.Contextimport android.net.wifi.WifiManagerimport java.io.IOExceptionimport java.io.InputStreamReaderimport java.io.LineNumberReaderimport java.util.*object SameLAN {    fun getWifiManager(context: Context): WifiManager {        return context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager    }    /**     * 获取IP地址。此方法获取的是转换后的ip地址     * @param context     * @return 转换后的IP地址: 类似 192.168.1.163     */    fun getIpAddress(context: Context): String {        return toIP(getIpAddressInt(context))    }    /**     * 获取IP地址。此方法获取的是没有转换的int类型的ip地址     * @param context     * @return 没有转换的ip地址:类似 -1560172352     */    fun getIpAddressInt(context: Context): Int {        val dhcpInfo = getWifiManager(context).dhcpInfo        return dhcpInfo.ipAddress    }    /**     * 获取网关。转换后的网关     * @param context     * @return 转换后的网关:类似 192.168.1.1     */    fun getGateway(context: Context): String {        return toIP(getGatewayInt(context))    }    /**     * 获取网关。此方法获取的是没有转换的int类型的网关     * @param context     * @return 没有转换的网关:类似 16885952     */    fun getGatewayInt(context: Context): Int {        val dhcpInfo = getWifiManager(context).dhcpInfo        return dhcpInfo.gateway    }    /**     * 获取子网掩码。获取的是转换后的子网掩码     * @param context     * @return 换后的子网掩码: 类似 255.255.255.0     */    fun getNetmask(context: Context): String {        return toIP(getNetmaskInt(context))    }    /**     * 获取子网掩码。此方法获取的是没有转换的int类型的子网掩码:16777215     * @param context     * @return 没有转换的子网掩码:类似16777215     */    fun getNetmaskInt(context: Context): Int {        val dhcpInfo = getWifiManager(context).dhcpInfo        return dhcpInfo.netmask    }    /**     * 判断是不是在同一个局域网。     * 原理是分别计算两部手机的 IP地址&子网掩码 的值,如果相等则表示在同一个局域网。     * @param localAddress :本机的IP地址。这个IP地址是String类型的IP地址,详细请看{@link SameLAN#getIpAddress}     * @param localMask :本机的子网掩码。这个子网掩码是String类型的子网掩码,详细请看{@link SameLAN#getNetmask}     * @param otherAddress :另一部手机的IP地址。这个IP地址是String类型的IP地址,详细请看{@link SameLAN#getIpAddress}     * @param otherMask :另一部手机的子网掩码。这个子网掩码是String类型的子网掩码,详细请看{@link SameLAN#getNetmask}     * @return :{@code true : 表示在同一个局域网} {@code false : 表示不在同一个局域网}     */    fun isInSameLAN(localAddress : String, localMask: String, otherAddress: String, otherMask: String): Boolean {        return isInSameLAN(toInt(localAddress),toInt(localMask),toInt(otherAddress),toInt(otherMask))    }    /**     * 判断是不是在同一个局域网。     * 原理是分别计算两部手机的 IP地址&子网掩码 的值,如果相等则表示在同一个局域网。     * @param localAddress :本机的IP地址。这个IP地址是没有转换后的IP地址,详细请看{@link SameLAN#getIpAddressInt}     * @param localMask :本机的子网掩码。这个子网掩码是没有转换后的子网掩码,详细请看{@link SameLAN#getNetmaskInt}     * @param otherAddress :另一部手机的IP地址。这个IP地址是没有转换后的IP地址,详细请看{@link SameLAN#getIpAddressInt}     * @param otherMask :另一部手机的子网掩码。这个子网掩码是没有转换后的子网掩码,详细请看{@link SameLAN#getNetmaskInt}     * @return :{@code true : 表示在同一个局域网} {@code false : 表示不在同一个局域网}     */    fun isInSameLAN(localAddress: Int, localMask: Int, otherAddress: Int, otherMask: Int): Boolean {        val local = localAddress and localMask        val other = otherAddress and otherMask        return local == other    }    /**     * 判断是不是在同一个局域网。     * 原理是根据TTL跳数来判断是不是在同一个局域网。他在设备B上有一个初始值,一般是32,64(常见),128,255(常见)。     * 如果AB不能直达,中间有路由器转发,那么每过一个路由,TTL会减一,比如TTL在B的初始值是64,到A是62,说明中间被两个路由转发过。     * 运用这个原理,当A去ping B的时候返回值如果不是32,64,128,255之一,而是略小于其中一个(比如62),那么说明A到B之间有路由器转发,即AB不在同一局域网内。     * @param ipAddress :需要确定是不是在同一个局域网的另一个IP。可以是 "192.168.4.174",也可以是 "www.baidu.com"     * @return {@code true : 表示在同一个局域网} {@code false : 表示不在同一个局域网}     */    fun isInSameLAN(ipAddress: String): Boolean {        var isInSameLAN = false        try {            val process = Runtime.getRuntime().exec("ping -c 1 -w 1 $ipAddress")            var returnMsg = LineNumberReader(InputStreamReader(process.inputStream)).use {                var sb = StringBuilder()                var readLine: String?                while (true) {                    readLine = it.readLine() ?: break                    sb.append(readLine)                }                sb.toString()            }            val splits = returnMsg.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()            for (i in splits.indices) {                val split = splits[i]                if (split.contains("ttl")) {                    if (split.contains("32") || split.contains("64") || split.contains("128") || split.contains("255")) {                        isInSameLAN = true                    }                }            }        } catch (e: IOException) {            e.printStackTrace()        }        return isInSameLAN    }    /**     * 将int类型的ip地址转换成String类型的     * @param ip     * @return     */    fun toIP(ip: Int): String {        val sb = StringBuffer()        sb.append(((ip and 0xff) as Int).toString())        sb.append('.')        sb.append(((ip shr 8 and 0xff) as Int).toString())        sb.append('.')        sb.append(((ip shr 16 and 0xff) as Int).toString())        sb.append('.')        sb.append(((ip shr 24 and 0xff) as Int).toString())        return sb.toString()    }    /**     * 将String类型的IP地址转换成int类型的IP地址     * @param ip     * @return     */    fun toInt(ip: String): Int {        val token = StringTokenizer(ip, ".")        var result: Int? = 0        result = Integer.parseInt(token.nextToken()) shl 24        result += Integer.parseInt(token.nextToken()) shl 16        result += Integer.parseInt(token.nextToken()) shl 8        result += Integer.parseInt(token.nextToken())        return result!!    }}

全部源码

参考资料

更多相关文章

  1. android游戏开发实例-可局域网对战的飞行棋(一)
  2. 基于xml类型的压缩数据流的android获取天气的方法
  3. 【转】Android -- 探究Android的多分辨率支持以及各种类型图标尺
  4. Android 仿淘宝2017添加地址
  5. 《局域网聊天——Android》
  6. 利用gson处理Java反射TypeToken泛型运行时类型擦除
  7. Android 保存联系人,包括部门\职位\传真\地址\照片

随机推荐

  1. Android的Handler总结(1)
  2. Android四大组件之 服务Service
  3. android 悬浮球的实现,全部界面可用
  4. Android(安卓)面试--请描述一下Activity
  5. Android使用BitmapFactory.Options解决加
  6. Android 屏幕分辩率相关问题
  7. Android组件化导致的代码不生效
  8. java回调C++
  9. 一个 Android 简易的新闻客户端
  10. Android Service Framework分析