Android 模拟器无法从套接字接收数据但相同的代码在 Genymotion 中工作
Android Emulator not able to receive data from socket but same code works in Genymotion
我正在通过 Java 套接字客户端从我的开发机器 (Mac) 向充当套接字服务器的 android 模拟器发送数据。所以基本上我首先启动 android 程序,它打开套接字端口并等待数据。
onStart 调用两个函数,一个是获取 IP,另一个是打开服务器套接字
@Override
protected void onStart() {
super.onStart();
getDeviceIpAddress();
new Thread(new start_siddhi_server()).start();
} //onStart
用于获取 IP 的代码是
public void getDeviceIpAddress() {
try {
//Loop through all the network interface devices
for (Enumeration<NetworkInterface> enumeration = NetworkInterface
.getNetworkInterfaces(); enumeration.hasMoreElements(); ) {
NetworkInterface networkInterface = enumeration.nextElement();
//Loop through all the ip addresses of the network interface devices
for (Enumeration<InetAddress> enumerationIpAddr = networkInterface.getInetAddresses(); enumerationIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = enumerationIpAddr.nextElement();
//Filter out loopback address and other irrelevant ip addresses
if (!inetAddress.isLoopbackAddress() && inetAddress.getAddress().length == 4) {
//Print the device IP address into the text view
Log.d("ip address", inetAddress.getHostAddress());
}
}
}
} catch (SocketException e) {
Log.e("ERROR:", e.toString());
}
}
用于启动服务器套接字的代码是
class start_siddhi_server implements Runnable {
@Override
public void run() {
Log.d("E", "starting siddhi server.........");
// Creating Siddhi Manager
SiddhiManager siddhiManager = new SiddhiManager();
String definition1 = " define stream temprature (room_no string, temp int);";
String query1 = "@info(name = 'query1') from temprature[temp >= 10] " +
"select room_no, temp " +
"insert into myOutputStream; ";
//Generating runtime
SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(definition1 + query1);
//Adding callback to retrieve output events from query
siddhiAppRuntime.addCallback("myOutputStream", new StreamCallback() {
@Override
public void receive(Event[] events) {
// for loop for iterating each event
for (Event event : events) {
Log.d("complex event = ", " Temp is " + event.getData(1));
} //end of for
} // end of receive method
}); // end of callback
// getting input handler
InputHandler inputHandlerA = siddhiAppRuntime.getInputHandler("temprature");
// starting siddhi app
siddhiAppRuntime.start();
// starting server socket
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(7000);
} catch (IOException e) {
e.printStackTrace();
}
Socket socket = null;
Log.d("E", " Siddhi server is waiting for sensor data.........");
while (true) {
try {
socket = serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
if (socket.isConnected() == true) {
Log.d("E", "connection is successful........");
InputStreamReader isReader = null;
try {
isReader = new InputStreamReader(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader input = new BufferedReader(isReader);
String line;
try {
while ((line = input.readLine()) != null) {
String[] tupleData = line.split(",");
String[] sensor_value = new String[10];
int i = 0;
for (String tuple : tupleData) {
String[] tupleValue = tuple.split("=");
sensor_value[i] = tupleValue[1];
i += 1;
}// key pair of tuple ends
Integer patient_id = Integer.valueOf(sensor_value[0]);
Integer sensor_id = Integer.valueOf(sensor_value[1]);
Integer uid = Integer.valueOf(sensor_value[2]);
Long egtl = Long.valueOf(sensor_value[3]);
Long edtl = 0L;
// Long edtl = Long.valueOf(sensor_value[4]);
Integer value = Integer.valueOf(sensor_value[4]);
inputHandlerA.send(new Object[]{uid, value});
// Log.d("patient_id = ", String.valueOf(patient_id));
// Log.d("sensor_id = ", String.valueOf(sensor_id));
// Log.d("uid = ", String.valueOf(uid));
// Log.d("egtl = ", String.valueOf(egtl));
}//while
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} //socket.isConnected()
} //while (true)
} //run
} // runnig_server
此外,清单文件中的权限是
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--The Paho Android Service needs the following permissions to work-->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
案例 1 .
当我 运行 它使用模拟器时,我得到以下 IP
10.0.2.15
ifconfig的结果也是一样
generic_x86:/ $ ifconfig eth0
eth0 Link encap:UNSPEC Driver virtio_net
inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0
inet6 addr: fe80::5054:ff:fe12:3456/64 Scope: Link
inet6 addr: fec0::5054:ff:fe12:3456/64 Scope: Site
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3565 errors:0 dropped:0 overruns:0 frame:0
TX packets:4068 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1190457 TX bytes:971370
但问题是我无法将数据发送到此端口。
我试过跟随IP
10.0.2.1
10.0.2.2
10.0.2.15
localhostip
案例 2 .
但是当我 运行 在 Genymotion 中使用相同的代码时,我得到以下结果
IP address: 192.168.56.101
当我向这个 IP 发送数据时,它工作正常。
我做错了什么?
如何让它在 android 模拟器上运行?
我想使用 e android 模拟器,因为它是免费的
编辑 1
问题已通过端口转发解决
adb forward tcp:7000 tcp:7000
现在的问题是,如果我使用的是模拟器,我将无法在分析器中看到网络数据
但如果我使用 Genymotion,我可以看到网络数据
你应该添加端口转发
adb forward tcp:7000 tcp:7000
然后使用localhost:7000
将数据从您的计算机发送到模拟器。
原因是模拟器创建了一个私有虚拟网络 (10.0.2.0),它不是 bridged,所以为了能够访问它,您必须转发端口。
我正在通过 Java 套接字客户端从我的开发机器 (Mac) 向充当套接字服务器的 android 模拟器发送数据。所以基本上我首先启动 android 程序,它打开套接字端口并等待数据。
onStart 调用两个函数,一个是获取 IP,另一个是打开服务器套接字
@Override
protected void onStart() {
super.onStart();
getDeviceIpAddress();
new Thread(new start_siddhi_server()).start();
} //onStart
用于获取 IP 的代码是
public void getDeviceIpAddress() {
try {
//Loop through all the network interface devices
for (Enumeration<NetworkInterface> enumeration = NetworkInterface
.getNetworkInterfaces(); enumeration.hasMoreElements(); ) {
NetworkInterface networkInterface = enumeration.nextElement();
//Loop through all the ip addresses of the network interface devices
for (Enumeration<InetAddress> enumerationIpAddr = networkInterface.getInetAddresses(); enumerationIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = enumerationIpAddr.nextElement();
//Filter out loopback address and other irrelevant ip addresses
if (!inetAddress.isLoopbackAddress() && inetAddress.getAddress().length == 4) {
//Print the device IP address into the text view
Log.d("ip address", inetAddress.getHostAddress());
}
}
}
} catch (SocketException e) {
Log.e("ERROR:", e.toString());
}
}
用于启动服务器套接字的代码是
class start_siddhi_server implements Runnable {
@Override
public void run() {
Log.d("E", "starting siddhi server.........");
// Creating Siddhi Manager
SiddhiManager siddhiManager = new SiddhiManager();
String definition1 = " define stream temprature (room_no string, temp int);";
String query1 = "@info(name = 'query1') from temprature[temp >= 10] " +
"select room_no, temp " +
"insert into myOutputStream; ";
//Generating runtime
SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(definition1 + query1);
//Adding callback to retrieve output events from query
siddhiAppRuntime.addCallback("myOutputStream", new StreamCallback() {
@Override
public void receive(Event[] events) {
// for loop for iterating each event
for (Event event : events) {
Log.d("complex event = ", " Temp is " + event.getData(1));
} //end of for
} // end of receive method
}); // end of callback
// getting input handler
InputHandler inputHandlerA = siddhiAppRuntime.getInputHandler("temprature");
// starting siddhi app
siddhiAppRuntime.start();
// starting server socket
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(7000);
} catch (IOException e) {
e.printStackTrace();
}
Socket socket = null;
Log.d("E", " Siddhi server is waiting for sensor data.........");
while (true) {
try {
socket = serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
if (socket.isConnected() == true) {
Log.d("E", "connection is successful........");
InputStreamReader isReader = null;
try {
isReader = new InputStreamReader(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader input = new BufferedReader(isReader);
String line;
try {
while ((line = input.readLine()) != null) {
String[] tupleData = line.split(",");
String[] sensor_value = new String[10];
int i = 0;
for (String tuple : tupleData) {
String[] tupleValue = tuple.split("=");
sensor_value[i] = tupleValue[1];
i += 1;
}// key pair of tuple ends
Integer patient_id = Integer.valueOf(sensor_value[0]);
Integer sensor_id = Integer.valueOf(sensor_value[1]);
Integer uid = Integer.valueOf(sensor_value[2]);
Long egtl = Long.valueOf(sensor_value[3]);
Long edtl = 0L;
// Long edtl = Long.valueOf(sensor_value[4]);
Integer value = Integer.valueOf(sensor_value[4]);
inputHandlerA.send(new Object[]{uid, value});
// Log.d("patient_id = ", String.valueOf(patient_id));
// Log.d("sensor_id = ", String.valueOf(sensor_id));
// Log.d("uid = ", String.valueOf(uid));
// Log.d("egtl = ", String.valueOf(egtl));
}//while
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} //socket.isConnected()
} //while (true)
} //run
} // runnig_server
此外,清单文件中的权限是
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--The Paho Android Service needs the following permissions to work-->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
案例 1 .
当我 运行 它使用模拟器时,我得到以下 IP
10.0.2.15
ifconfig的结果也是一样
generic_x86:/ $ ifconfig eth0
eth0 Link encap:UNSPEC Driver virtio_net
inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0
inet6 addr: fe80::5054:ff:fe12:3456/64 Scope: Link
inet6 addr: fec0::5054:ff:fe12:3456/64 Scope: Site
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3565 errors:0 dropped:0 overruns:0 frame:0
TX packets:4068 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1190457 TX bytes:971370
但问题是我无法将数据发送到此端口。
我试过跟随IP
10.0.2.1
10.0.2.2
10.0.2.15
localhostip
案例 2 .
但是当我 运行 在 Genymotion 中使用相同的代码时,我得到以下结果
IP address: 192.168.56.101
当我向这个 IP 发送数据时,它工作正常。
我做错了什么?
如何让它在 android 模拟器上运行?
我想使用 e android 模拟器,因为它是免费的
编辑 1
问题已通过端口转发解决
adb forward tcp:7000 tcp:7000
现在的问题是,如果我使用的是模拟器,我将无法在分析器中看到网络数据
但如果我使用 Genymotion,我可以看到网络数据
你应该添加端口转发
adb forward tcp:7000 tcp:7000
然后使用localhost:7000
将数据从您的计算机发送到模拟器。
原因是模拟器创建了一个私有虚拟网络 (10.0.2.0),它不是 bridged,所以为了能够访问它,您必须转发端口。