android wifi组播发送开发日常问题汇总

问题一:手机自身作为热点用常用的获取IP的方法无法获取自身IP

研究:自身作为热点或未开启WIFI,网上常用获取IP的方法中判断WIFI的enable是无法行的,导致获取不到IP

解决方案:获取接口下各个赋值的IP,此赋值可以是USB WLAN 3G等,风险点:厂商修改此赋值名导致无法获取

public static InetAddress getIpAddress() throws SocketException {
   InetAddress inetAddress = null;
   InetAddress myAddr = null;
   try {
      for (Enumeration<NetworkInterface> networkInterface = NetworkInterface
            .getNetworkInterfaces(); networkInterface.hasMoreElements();) {
         NetworkInterface singleInterface = networkInterface.nextElement();
         for (Enumeration<InetAddress> IpAddresses = singleInterface.getInetAddresses(); IpAddresses
               .hasMoreElements();) {
            inetAddress = IpAddresses.nextElement();
            if (!inetAddress.isLoopbackAddress()
                  && (singleInterface.getDisplayName().contains("wlan0"))) {
               // FIXME 此处要注意是否有多个IP
               myAddr = inetAddress;
            }
         }
      }
   } catch (SocketException ex) {
      throw ex;
   }
   return myAddr;
}


问题二:发送组播端如果自身作为热点无法发送组播

研究:网上所确定的组播地址范围试验很多值无法使用,返回不可用的组播地址的错误。

解决方案:根据问题一获取的自身IP来获取自身真正的组播地址:

/**
 * 获取组播地址
 * 
 * @param inetAddr :自身IP
 * @return
 * @throws SocketException <可解决作为热点时无法发送组播问题>
 */
private InetAddress getBroadcast(InetAddress inetAddr) throws SocketException {
   if (inetAddr == null) {
      return null;
   }
   NetworkInterface temp;
   InetAddress iAddr = null;
   try {
      temp = NetworkInterface.getByInetAddress(inetAddr);
      List<InterfaceAddress> addresses = temp.getInterfaceAddresses();
      for (InterfaceAddress inetAddress : addresses) {
         iAddr = inetAddress.getBroadcast();
      }
   } catch (SocketException e) {
      e.printStackTrace();
      throw e;
   }
   return iAddr;
}

问题三:指定端口发送出去的组播无法根据此端口再获取对方发来的定向播

研究:此端口无论是否设置setLooperMode都能获取到自身发送出去的组播?(尚不清楚why),导致接收端根据此端口号发送出的定向包获取的非常慢,且组播端还要过滤接收的播信息。

解决方案:接收端接收到组播后另启动一个端口号,根据接收到组播能获取发送端的IP mDiscoverInfo.IP=mDatagramPacket.getAddress().getHostAddress();

然后发送定向包,发送组播端监听新的端口号来接收组播。

弊端:占用多个端口号



问题四:组播在IPV6-only的环境下如何发送?如何判断网络为IPV6的网络?

研究:组播在IP为Inet6Address类型时,通过getBroadcast()接口返回的null,获取不到组播地址。无法发送组播。

解决方案:1在路由器域内通过.设置公用的IPV6环境地址:mBroadcastAdd = InetAddress.getByName("FF05:0:0:0:0:0:0:2");然后通过发送组播的接口发送可发送组播。

接收方必须jionGroup(mBroadcastAdd )才能获取数据

2.在IPV6的环境下根据下面接口判断环境为v4还是v6:

public static InetAddress getIpAddress() throws SocketException {
InetAddress inetAddress = null;
InetAddress myAddr = null;
List<InetAddress> ipv6InetAddress = new ArrayList<InetAddress>();
try {
for (Enumeration<NetworkInterface> networkInterface = NetworkInterface
.getNetworkInterfaces(); networkInterface.hasMoreElements();) {
NetworkInterface singleInterface = networkInterface.nextElement();
for (Enumeration<InetAddress> IpAddresses = singleInterface.getInetAddresses(); IpAddresses
.hasMoreElements();) {
inetAddress = IpAddresses.nextElement();
if (!inetAddress.isLoopbackAddress()
&& (singleInterface.getDisplayName().contains("wlan0"))
&& singleInterface.supportsMulticast()) {
// FIXME 此处要注意是否有多个IP
if (inetAddress instanceof Inet4Address) {
myAddr = inetAddress;
}
if (inetAddress instanceof Inet6Address) {
ipv6InetAddress.add(inetAddress);
}


}
}
}
if (ipv6InetAddress.size() > 1) {
// 多个IP时为IPV6网络
// FIXME 暂时无法判断哪个IP是所需要的,后续有待商榷
myAddr = ipv6InetAddress.get(0);
}
} catch (SocketException ex) {
throw ex;
}
return myAddr;
}

mBroadcastAdd = IpUtils.getIpAddress();
if (mBroadcastAdd instanceof Inet4Address) {
mBroadcastAdd = getBroadcast(mBroadcastAdd);
}
if (mBroadcastAdd instanceof Inet6Address) {
mBroadcastAdd = InetAddress.getByName("FF05:0:0:0:0:0:0:2");
if (DBG)
Log.e("swc", "sendmult network is ipv6");
}

未完待续。。。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值