Android emulatorにIPアドレスを設定して開発マシン(macOS)と通信したい
やりたいことはタイトル通りなのですが、初心者のため何がわかっていないのか
わからないような感じで、ご教授いただければ幸いです。
やったこと。
I.http://tuntaposx.sourceforge.net/download.xhtml
からtuntapをダウンロードしてインストールし、/dev/にtap0〜15までできていることを確認しました。
Ⅱ.http://lakm.us/logit/2013/01/handy-tap-interface-mac-osx/
を参考に、/usr/local/bin/setup-tap1.pyを作成し、ターミナルで実行しました。
内容は少し変えていて、下記のようにしました(Android emulator起動時にtap1の
fdを与える為、print dev_fileを追加(そもそもこれがfdなのかもよくわかっていないですが)。
#!/usr/bin/python
import os
while 1:
try:
file_path = '/dev/tap1'
dev_file = os.open(file_path, os.O_RDWR)
print "dev_file is the following number."
print dev_file
interface = 'tap1'
while 1:
pass
except:
print "tap interface is closing"
exit()
break
Ⅲ.ifconfigでtap1が作られていることを確認し、
sudo ifconfig tap1 192.168.100.103
を実行して、開発マシンが存在しているLAN(192.168.100.x)にtap1を繋げたつもりです。
Ⅳ.ターミナルからAndroid emulatorを起動するため、下記のコマンドを実施しました。
$ sudo /Users/自分の名前/Library/Android/sdk/emulator/emulator \
-avd Pixel_2_XL_API_29 -qemu -netdev tap,id=guest0,fd=3
fdの3はⅡで出力されてきた数字です。
ⅴ.タイトル通りのことができているかを確認する為、別のターミナルを開いて、
下記のサーバープログラム(相手のIPアドレスを出力)を実行しました。
int main(int argc, char* argv[]) {
int servSock;
int clitSock;
struct sockaddr_in servSockAddr;
struct sockaddr_in clitSockAddr;
unsigned short servPort;
unsigned int clitLen;
char A;
servPort = 50000;
if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0 ){
perror("socket() failed.");
exit(EXIT_FAILURE);
}
memset(&servSockAddr, 0, sizeof(servSockAddr));
servSockAddr.sin_family = AF_INET;
servSockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servSockAddr.sin_port = htons(servPort);
if (bind(servSock, (struct sockaddr *) &servSockAddr,sizeof(servSockAddr) ) < 0 ) {
perror("bind() failed.");
exit(EXIT_FAILURE);
}
if (listen(servSock, QUEUELIMIT) < 0) {
perror("listen() failed.");
exit(EXIT_FAILURE);
}
while(1) {
clitLen = sizeof(clitSockAddr);
if ((clitSock = accept(servSock, (struct sockaddr *) &clitSockAddr, &clitLen)) < 0) {
perror("accept() failed.");
exit(EXIT_FAILURE);
}
printf("accept done\n");
read(clitSock,&A,1);
printf("client send : %c\n",A);
A++;
write(clitSock,&A,1);
printf("connected from %s.\n", inet_ntoa(clitSockAddr.sin_addr));
close(clitSock);
}
return EXIT_SUCCESS;
}
Android Studioで作成した下記のクライアントプログラムは下記です。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView tv1 = (TextView) findViewById(R.id.tv1);
final TextView tv2 = (TextView) findViewById(R.id.tv2);
final TextView tv3 = (TextView) findViewById(R.id.tv3);
final TextView tv4 = (TextView) findViewById(R.id.tv4);
final TextView tv5 = (TextView) findViewById(R.id.tv5);
final TextView tv6 = (TextView) findViewById(R.id.tv6);
final Handler Handlertest = new Handler();
final BufferedWriter wr = null;
final Character data = 'J';
new Thread(new Runnable() {
@Override
public void run() {
try {
InetAddress IP = InetAddress.getByAddress(new byte[]{(byte)192, (byte) 168,100,102});
final String IPconfirm=IP.getHostAddress();
final String Nconfirm=IP.getHostName();
Handlertest.post(new Runnable() {
@Override
public void run() {
tv1.setText("connection to : "+IPconfirm);
tv2.setText("connection to : "+Nconfirm);
}
});
Socket soc = new Socket(IP, 50000);
InetAddress conconfirm = soc.getInetAddress();
final String IPconfirm2=conconfirm.getHostAddress();
final String Nconfirm2=conconfirm.getHostName();
OutputStream SockOpSt = soc.getOutputStream();
OutputStreamWriter OSwr = new OutputStreamWriter(SockOpSt);
BufferedWriter Bwr = new BufferedWriter(OSwr);
Bwr.write(data);
Bwr.flush();
InputStream SockIpSt = soc.getInputStream();
InputStreamReader ISrd = new InputStreamReader(SockIpSt);
BufferedReader Brd = new BufferedReader(ISrd);
String line;
while((line = Brd.readLine()) != null){
final String lineforHl = line;
Handlertest.post(new Runnable() {
@Override
public void run() {
tv3 .setText("server send : "+lineforHl);
}
});
}
Bwr.close();
Brd.close();
soc.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
思惑としては、サーバー側のプロセスの出力に「connected from 192.168.100.103」と表示されて
欲しいのですが、「connected from 192.168.100.102」(開発マシンのIPアドレス)と出力されます。
お伺いしたいことは以下の4つです。
- tapそのものにIPアドレスを設定するっていうのは考え方として間違ってますでしょうか?
(pingコマンドをうっても、request time outになります) - なんでクライアント側であるエミュレータのIPアドレスが192.168.100.103にならないのか。
- エミュレータの起動にやたらと時間がかかる(あさに、Ⅲのコマンドを実行してほっといて、
帰ってきたらいつの間にか起動してた状態です)のですが、何かおかしいのでしょうか?
どういった対策ができますでしょうか? - エミュレータ起動時にターミナルに下記の文字の出力がされてきて、no pearやwarningやdata not found
などの単語が出てくるので、解決した方が良さそうなのですが、どうしたらいいのでしょうか?
エミュレータ起動時にターミナルに出てくる文字(たくさん出てくるので、抜粋してます)
qemu-system-x86_64: warning: netdev guest0 has no peer
emulator: WARNING: Running on a sytem with less than 8 logical cores. Setting number of virtual cores to 1
Qt WebEngine ICU data not found at /Users/joshuaduong/qt-build-5.12.1/install-darwin-x86_64/resources. Trying parent directory...
どなたか教えていただけると助かります。