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

来源:互联网 发布:网络加速的原理 编辑:程序博客网 时间:2024/05/21 21:44

问题一:手机自身作为热点用常用的获取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");
}

未完待续。。。

0 0