我制作了一个Android应用程序,该应用程序需要连接wamp服务器提供的一个本地数据库。首先使用android虚拟设备(AVD)我的IP来连接服务器,第一次使用的是:10.0.2.2
。我的AVD可以正常连接,但是当我尝试直接在设备上进行连接时,他找不到具有此10.0.2.2
IP的本地服务器。此时,我已经将IP更改192.168.1.5
为我的LAN电缆IP,设备和AVD都在正常运行...但是有时我需要将我的连接更改为wifi,从而更改了IP。我的源代码中的一个IP将无法发布android应用,因为其他人将拥有其他LAN IP地址。
为了解决此问题,我开始寻找解决方案,例如动态获取LAN IP。为此,我构建了该Java应用程序作为测试:
public class test {
public static void main(String[] args) throws Exception
{
String roundHost = null;
Enumeration<NetworkInterface> n = NetworkInterface.getNetworkInterfaces();
for (; n.hasMoreElements();)
{
NetworkInterface e = n.nextElement();
Enumeration<InetAddress> a = e.getInetAddresses();
for (; a.hasMoreElements();)
{
InetAddress addr = a.nextElement();
if (addr.isSiteLocalAddress()){
String pureHost = addr.getByName(addr.getHostName()).toString();
roundHost = addr.getHostAddress();
pureHost = pureHost.substring(addr.getHostName().length()+1);
if(!roundHost.equals(pureHost))
break;
}
}
}
System.out.println(roundHost);
}
}
作为输出,此java应用程序为我提供了正确的LAN wifi IP或什至是LAN电缆IP192.168.1.3
或192.168.1.7
。从这里,我制作了一个“ IPParser”以用于我的android应用程序:
public class IPParser {
String pureHost, roundHost = null;
public IPParser() throws UnknownHostException{
Enumeration<NetworkInterface> n = null;
try {
n = NetworkInterface.getNetworkInterfaces();
} catch (SocketException e1) {
e1.printStackTrace();
}
for (; n.hasMoreElements();)
{
NetworkInterface e = n.nextElement();
Enumeration<InetAddress> a = e.getInetAddresses();
for (; a.hasMoreElements();)
{
InetAddress addr = a.nextElement();
if (addr.isSiteLocalAddress()){
pureHost = addr.getByName(addr.getHostName()).toString();
roundHost = addr.getHostAddress();
pureHost = pureHost.substring(addr.getHostName().length()+1);
if(!roundHost.equals(pureHost))
break;
}
}
}
}
public String returnIp() {
return roundHost;
}
}
如您所见,它非常相似;区别只是为了适应所需语法而进行了一些结构性更改。现在出现了真正的问题:当我尝试在我的AVD中运行此解析器时,我的ip是10.0.2.15
并且直接在我的设备中运行ip返回是192.168.1.6
-显然,android应用程序崩溃了,因为它找不到要连接的本地服务器。
我的IP配置信息:
我不是网络专家,所以请问,请放轻松,如果我说的是技术上的错误或邻近之处,请编辑并更正我..最后,我问:
为什么会发生这种情况,以及可以采取什么措施解决此问题?
您提到(10.0.2.2
和192.168.1.5
)的IP来自两个不同的网络,这很有意义,因为文档指出:
仿真器的每个实例都在虚拟路由器/防火墙服务后面运行,该服务将其与开发计算机的网络接口和设置以及Internet隔离开。仿真设备无法在网络上看到您的开发机器或其他仿真器实例。而是只看到它通过以太网连接到路由器/防火墙。
每个实例的虚拟路由器管理10.0.2 / 24网络地址空间-路由器管理的所有地址均采用10.0.2。的形式,其中为数字。该空间内的地址由仿真器/路由器预先分配,如下所示:
这意味着使用AVD时会创建一个虚拟网络,该虚拟网络将设备和计算机作为其中的一部分。在您的情况下,您的本地计算机将使用10.0.2.2
该虚拟网络和AVD中的地址10.0.2.15
。但是,当您直接通过设备连接时,计算机的IP(以及设备的IP)位于LAN的地址空间(即192.168.1.5
和192.168.1.6
)中。
您发布的代码可以解析主机的IP地址,但是如果您希望设备自动解析服务器的IP地址,并且可以保证它们始终都连接到同一LAN,则可以使用多播UDP消息(我没有找不到很好的资源,但是您可以从此处,此处和此处开始)。这种类型的通信将UDP数据报发送到网络中的特定多播IP地址和端口,网络中的其他设备正在侦听该特定IP地址和端口。我在需要在网络中找到计算机的Android应用程序中使用了该方案,因此我知道它可以正常工作。如果需要,我可以共享一些代码。
以下代码段是实现网络中计算机搜索的代码段。所使用的Android应用程序可以控制网络中运行服务器应用程序的任何计算机的鼠标和键盘。
Android客户端
public void findComputers(View v) {
try {
int port = 4444;
String multicastAddr = "224.168.1.0";
DatagramSocket socket = new DatagramSocket(port);
socket.setSoTimeout(300);
InetAddress group = InetAddress
.getByName(multicastAddr);
DatagramPacket packet = new DatagramPacket(new byte[] { 1 }, 1,
group, port);
socket.send(packet);
// Give time to the servers to respond
Thread.sleep(100);
while (true) {
try {
// Listen for the servers responses
byte[] buffer = new byte[256];
packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
String data = new String(packet.getData());
// Information sent from servers include the host's name
// and IP addres separated by a semicolon.
String[] parts = data.split(";");
// Add a server to the result list.
Computer computer = new Computer(parts[1].trim(),
parts[0].trim());
this.computers.put(computer.getName(), computer);
} catch (InterruptedIOException ex) {
break;
}
}
socket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
String output = "No computers found.";
if (this.computers.size() > 0) {
output = this.computers.size() + " computer(s) found.";
this.fillComputers();
}
Toast.makeText(this, output, Toast.LENGTH_SHORT).show();
}
服务器
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
/**
* Receives UDP broadcast packets in the default port requesting for server name
* and IP, broadcasting the information in return.
*
* @author jfacorro
*
*/
public class NameResolverService extends Thread {
private InetAddress localAddress = null;
private byte[] localAddressData = null;
private MulticastSocket socket = null;
private boolean exit = false;
public NameResolverService() {
}
public void exit() {
this.exit = true;
this.socket.close();
}
@Override
public void run() {
try {
int port = 4444;
String multicastAddr = "224.168.1.0";
// Get current address
this.localAddress = InetAddress.getLocalHost();
this.socket = new MulticastSocket(port);
InetAddress group = InetAddress.getByName(multicastAddr);
this.socket.joinGroup(group);
this.localAddressData = (this.localAddress.getHostAddress() + ";" + this.localAddress
.getHostName()).getBytes();
} catch (IOException ex) {
this.notified.notified(ex.getMessage());
ex.printStackTrace();
}
while (!this.exit) {
try {
byte[] buffer = new byte[1];
DatagramPacket packet = new DatagramPacket(buffer,
buffer.length);
socket.receive(packet);
InetAddress address = packet.getAddress();
int port = packet.getPort();
packet = new DatagramPacket(this.localAddressData,
this.localAddressData.length, address, port);
socket.send(packet);
} catch (IOException e) {
if(!this.exit)
e.printStackTrace();
}
}
this.socket.close();
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句