获取模拟器IP以连接到android模拟器(virtualbox)

时间:2019-02-03 16:19:57

标签: ip adb emulation

我的操作系统是Windows 10。

我在模拟器中使用android x86。

我将virtualbox用作仿真器,并将virtualbox的网络设置为:

-桥适配器(连接类型)

-Intel(R)Dual Band Wireless-AC 3168(名称)

-英特尔PRO / 1000 MT桌面(8254OEM)->(适配器类型)

-全部允许(混杂模式)

我设置它是因为这样可以使我的模拟器连接到互联网。

我使用python运行使用模拟器的脚本。

问题是当我使用不同的网络时,仿真器的IP已更改。.

因此,当我更改使用的网络时,代码的某些部分无法正常工作,代码为:

from subprocess import Popen, PIPE
import os

ip_emulator ='192.168.100.15' #the ip got from "ALT + F1" and type ipconfig on emulator
fileadb = 'adb.exe'
pathsys32 = r'C:\Users\admin\AppData\Local\Android\Sdk\platform-tools'
adb = os.path.join(pathsys32, fileadb)
cek = Popen([adb, 'connect', ip_emulator], stdout=PIPE, stderr=PIPE)

由于仿真器中的ip更改是由于更改了我使用的网络(例如,从家庭使用的网络更改为办公室网络或使用移动调制解调器)引起的。

我应该编写代码以检测仿真器ip,以确保我的adb已连接到仿真器。

该怎么做?可以通过python将其插入仿真器外部,而无需进入仿真器(例如,按ALT + F1,然后键入ifconfig)。

我已经尝试使用:“ arp -a” 但是有时ip显示有时没有。

已经尝试“ netstat -a” 那里没有仿真器ip

通过arp检测的代码:

from subprocess import Popen, PIPE
import os
import re

arpfile = 'ARP.EXE'
fileadb = 'adb.exe'
pathsys32 = r'C:\Windows\System32'
arp = os.path.join(pathsys32, arpfile)
adb = os.path.join(pathsys32, fileadb)

def detectiparp():
    cek = Popen([arp, '-a'], stdout=PIPE, stderr=PIPE)
    out, err = cek.communicate()
    outdata = (out.decode('utf-8')).split('\n')
    for i in outdata:
        mac = '08-00-27-ce-9e-8c'
        rexmac = re.search(mac, i)
        if rexmac:
            ipre = '([0-9]{0,}\.[0-9]{0,}\.[0-9]{0,}\.[0-9]{0,})\s.+?08-00-27-ce-9e-8c'
            iprex = re.search(ipre, i)
            ip_emu = iprex.group(1)
            return ip_emu
        else:
            return False

ip_emulator = detectiparp()

cek = Popen([adb, 'connect', ip_emulator], stdout=PIPE, stderr=PIPE)

我已经阅读:

How to get the Android Emulator's IP address?

How to connect to AVD

How to get the IP address of an emulator to communicate to the local server

我认为所有答案都是“从模拟器内部获得模拟器IP”或“使用默认IP组(10.0.2.2)”

所以,我解释一下,只有当我在virtualbox中使用的连接类型是NAT类型时,才会发生IP 10.0.2.2,但是使用该设置,我的模拟器无法连接到Internet。

已经尝试使用:

第一个网络设置为NAT,第二个网络设置为Bridge,但是如果我使用其他网络,则IP更改为C类(192.169.x.x),并且仿真器的ip仍会更改。

如果我知道如何(从主机/笔记本电脑/仿真器外部)检测仿真器IP,我可以编写代码,或者可以使用python模块检测它?

1 个答案:

答案 0 :(得分:0)

好的,两天了,没有回应...

以及所有具有相同问题的问题,仍然没有答案。...

我已经找到答案了,所以我在这里分享它...有人为我的答案提供帮助,请给我评分...

从仿真器外部检测仿真器的工具使用的是'arp -a',但是在执行此操作之前,我们必须先对仿真器执行ping操作,以使命令'arp -a'给出结果。

所以我创建了一个脚本,每次打开脚本时都会自动执行。

我的模拟器设置之前已经解释过,我没有解释的是我以无头模式打开模拟器。...

这是我的脚本:

from __future__ import print_function
import os
import time
import re
from subprocess import Popen, PIPE
from io import StringIO
from contextlib import redirect_stdout
import ipaddress as ipaddr
import socket

pathvbox = r'C:\Program Files\Oracle\VirtualBox'
pathadb = r'C:\Users\admin\AppData\Local\Android\Sdk\platform-tools'
fileadb = 'adb.exe'
filevboxmanage = 'VBoxManage.exe'
adb = os.path.join(pathadb, fileadb)
vbmanage = os.path.join(pathvbox, filevboxmanage)

arpfile = 'ARP.EXE'
pathsys32 = r'C:\Windows\System32'
arp = os.path.join(pathsys32, arpfile)

pathpy3 = r'C:\Users\admin\AppData\Local\Programs\Python\Python37'
py3file = 'python3.exe'
python3 = os.path.join(pathpy3, py3file)

def startemulator():
#function to run emulator in headless (Android x86)
    cek = Popen([vbmanage, 'startvm', 'andro', '--type', 'headless'], stdout=PIPE, stderr=PIPE)
    time.sleep(5)

def killemulator():
    #function to shutdown emulator in savestate condition
    sstate = Popen([vbmanage, 'controlvm', 'andro', 'savestate'], stdout=PIPE, stderr=PIPE)
    shutdown = Popen([vbmanage, 'controlvm', 'andro', 'savestate', 'shutdown', '/s', '/t', '10'], stdout=PIPE, stderr=PIPE)
    out, err = shutdown.communicate()

def ping(str):
    p1 = Popen(['ping', '-c', '3', str], stdout=PIPE, stderr=PIPE)
    p1.communicate()

def get_own_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(("8.8.8.8", 80))
    return s.getsockname()[0]

def ping_all_ip():
    ipnow = get_own_ip()
    inet = ipaddr.ip_interface(ipnow + '/24')
    allip = inet.network
    f = StringIO()
    with redirect_stdout(f):
        for ip in allip:
            print(ip)
        all_ip = f.getvalue().split('\n')

    for ip in all_ip:
        ping(ip)

def detectiparp():
    cek = Popen([arp, '-a'], stdout=PIPE, stderr=PIPE)
    out, err = cek.communicate()
    outdata = (out.decode('utf-8')).split('\n')
    for i in outdata:
        mac = '(08-00-27-ec-9c-8e)' #put your mac address here
        rexmac = re.search(mac, i)
        if rexmac:
            ipre = '([0-9]{0,}\.[0-9]{0,}\.[0-9]{0,}\.[0-9]{0,})\s.+?' + mac
            iprex = re.search(ipre, i)
            iponline = iprex.group(1)
        else:
            pass

    try:
        if iponline:
            return iponline
        else:
            return False
    except:
        return False

def detectip():
    while True:
        ping_all_ip()
        try:
            ipis = detectiparp()
            if ipis:
                break
        except:
            continue
    return ipis

def turnonADB():
    ip_emu = detectip()
    while True:
        cek = Popen([adb, 'connect', ip_emu], stdout=PIPE, stderr=PIPE)
        out, err = cek.communicate()
        outstring = out.decode('utf-8')
        try:
            failed = re.search('failed', outstring)
            if not failed:
                break
        except:
            continue

if __name__ == '__main__':
    startemulator()
    turnonADB()

仅此而已...

我做什么是......:

只检测我的IP ...

然后将其转换为cidr / 24,

然后再次提取,

ping提取的所有IP

ping我网络中的所有IP后,打开“ arp -a”命令。

因为仿真器需要一些时间来“激活/打开/运行”,所以当您对仿真器ip进行ping操作时,它有可能无法激活/没有响应,因此此脚本会自动重新处理ping并在arp中将其终止-a。

如果仍未显示“ arp -a”仿真器的mac地址,则表示仿真器正在打开。

欢呼..希望为任何人提供帮助都需要答案。

管理员可以关闭此问题。...谢谢。...