创建TCP套接字时无法识别Android主机名
大家好,我已经为此挣扎了一段时间,现在找不到解决办法 在java中,此代码起作用:创建TCP套接字时无法识别Android主机名,android,sockets,networking,jmdns,Android,Sockets,Networking,Jmdns,大家好,我已经为此挣扎了一段时间,现在找不到解决办法 在java中,此代码起作用: InetAddress serverAddr = InetAddress.getByName("myservice.local"); Socket socket = new Socket(serverAddr, PoolServerAddress.DEFAULT_PORT); 在安卓系统中,同样的方法不起作用。我已尝试删除“.local”,并在清单中添加所有必要的置换: <uses-permission
InetAddress serverAddr = InetAddress.getByName("myservice.local");
Socket socket = new Socket(serverAddr, PoolServerAddress.DEFAULT_PORT);
在安卓系统中,同样的方法不起作用。我已尝试删除“.local”,并在清单中添加所有必要的置换:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
我还尝试在执行代码之前添加多播锁,但没有办法解决这个问题
我得到以下例外情况:
06-03 13:18:14.438: W/System.err(31636): java.net.UnknownHostException: Unable to
resolve host <server_name>: No address associated with hostname
06-03 13:18:14.438: W/System.err(31636): at
java.net.InetAddress.lookupHostByName(InetAddress.java:434)
06-03 13:18:14.438: W/System.err(31636): at
java.net.InetAddress.getAllByNameImpl(InetAddress.java:239)
06-03 13:18:14.438: W/System.err(31636): at
java.net.InetAddress.getByName(InetAddress.java:292)
06-03 13:18:14.438: W/System.err(31636): at
com.example.jelly_test.MainActivity.connect(MainActivity.java:113)
06-03 13:18:14.438: W/System.err(31636): at
com.example.jelly_test.MainActivity$ResolvingThread.run(MainActivity.java:71)
06-03 13:18:14.438: W/System.err(31636): Caused by: libcore.io.GaiException:
getaddrinfo
failed: EAI_NODATA (No address associated with hostname)
06-03 13:18:14.438: W/System.err(31636): at libcore.io.Posix.getaddrinfo(Native
Method)
06-03 13:18:14.438: W/System.err(31636): at
libcore.io.ForwardingOs.getaddrinfo(ForwardingOs.java:55)
06-03 13:18:14.438: W/System.err(31636): at
java.net.InetAddress.lookupHostByName(InetAddress.java:415)
06-03 13:18:14.438: W/System.err(31636): ... 4 mor
06-03 13:18:14.438:W/System.err(31636):java.net.UnknownHostException:无法
解析主机:没有与主机名关联的地址
06-03 13:18:14.438:W/系统错误(31636):在
java.net.InetAddress.lookupHostByName(InetAddress.java:434)
06-03 13:18:14.438:W/系统错误(31636):在
java.net.InetAddress.getAllByNameImpl(InetAddress.java:239)
06-03 13:18:14.438:W/系统错误(31636):在
java.net.InetAddress.getByName(InetAddress.java:292)
06-03 13:18:14.438:W/系统错误(31636):在
com.example.jelly_test.MainActivity.connect(MainActivity.java:113)
06-03 13:18:14.438:W/系统错误(31636):在
com.example.jelly_test.MainActivity$ResolvingThread.run(MainActivity.java:71)
06-03 13:18:14.438:W/System.err(31636):由libcore.io.ga异常引起:
getaddrinfo
失败:EAI_NODATA(没有与主机名关联的地址)
06-03 13:18:14.438:W/System.err(31636):位于libcore.io.Posix.getaddrinfo(本机)
(方法)
06-03 13:18:14.438:W/系统错误(31636):在
libcore.io.ForwardingOs.getaddrinfo(ForwardingOs.java:55)
06-03 13:18:14.438:W/系统错误(31636):在
java.net.InetAddress.lookupHostByName(InetAddress.java:415)
06-03 13:18:14.438:W/系统错误(31636):。。。上午4点
如果我提供ip而不是服务,它可以工作,但我需要能够提供名称。
此外,我还尝试将解析名称添加到ip中,但速度很慢,仅适用于办公室的内部服务,但我们的一些服务是网络外部的,但它们仍然可以通过java版本访问,但不能通过android访问。
还有什么我可以试试的吗?非常感谢,因为我的想法不多了
编辑:
我认为我的问题是因为android中存在一个问题,它只接受以下情况:
myservice.company.com根据要求,这里是我找到的临时解决此问题的选项,因为即使在最新的Android版本(撰写本文时为4.4版)中,该漏洞仍然没有得到修复 确保将问题中指示的所有必需权限添加到清单中 备选案文1: 如果您不知道这是一个很好的教程,请使用JmDNS库查找可用服务器的列表并找到您的服务器: 这个方法很慢,我发现有些服务没有显示(它们必须用zeroconf进行广告) 备选案文2: 请您的用户输入完全限定的域名,例如name.comany.com,而不是name.local 备选案文3: 这确实是一种黑客行为,但如果您知道FQDN的类型为someName.mycop.com,并且用户输入了someName.local,则必须删除“.local”,并尝试猜测域是什么:
private String getTargetIp(String host) {
System.out.println("Will try to create socket with "+host);
MulticastLock multicastLock = null;
String ipToReturn = null;
Socket socket = null;
try {
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
multicastLock = wifiManager.createMulticastLock("any_name");
multicastLock.acquire();
DhcpInfo info = wifiManager.getDhcpInfo();
int ip = info.ipAddress;
InetAddress local = getInetAddress(ip);
String localHostName = local.getCanonicalHostName();
Log.d(TAG, "Device ip addr1 = "+local +" name= "+localHostName);
String[] temp = localHostName.split("\\.");
//replace the first part with our name and obtain FQDN
String targetFullHostName=localHostName.replace(temp[0], host);
Log.d(TAG, "targetFullHostName = "+targetFullHostName);
//this is not mandatory but here we are trying to retrieve the ip address
//it maybe also a way to check if we guessed right
InetAddress serverAddr = InetAddress
.getByName(targetFullHostName);
socket = new Socket(serverAddr,
PoolServerAddress.DEFAULT_PORT);
ipToReturn = socket.getInetAddress().getHostAddress();
Log.d(TAG, "socket remote address=" + ipToReturn);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}catch(Exception e){
Log.e(TAG, "Other Exception");
}
finally {
if (multicastLock != null)
multicastLock.release();
if(socket!=null)
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return ipToReturn;
}
备选案文4:
从api级别16开始,您可以使用Android Service Discovery listener列出可用的服务并找到您正在寻找的服务。这与JmDNS的工作方式类似:您发现所有服务并尝试在列表中找到您的服务。这是指向文档的链接:您找到解决方案了吗?如果可以的话,请把它贴在这里好吗?我遇到了同样的问题…我已经写了答案,很抱歉没有找到明确的解决办法