【问题标题】:Android Emulator not able to receive data from socket but same code works in GenymotionAndroid Emulator 无法从套接字接收数据,但相同的代码在 Genymotion 中工作
【发布时间】:2023-08-24 08:47:01
【问题描述】:

我正在通过 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" />

案例一。

当我使用模拟器运行它时,我得到以下 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 发送数据时,它可以工作。


我做错了什么?

如何让它适用于安卓模拟器?

我想使用 e android 模拟器,因为它是免费的????

编辑 1

问题已通过端口转发解决

 adb forward tcp:7000 tcp:7000

现在的问题是如果我使用模拟器,我无法在分析器中看到网络数据

但如果我使用 Genymotion ,我可以看到网络数据

【问题讨论】:

  • to android emulator which acts as the socket server. 。我认为是在模拟器上运行的 android 应用程序。该 android 应用程序打开一个 serversocket。

标签: android android-emulator genymotion serversocket


【解决方案1】:

你应该添加一个端口转发

adb forward tcp:7000 tcp:7000

然后使用localhost:7000 将数据从您的计算机发送到模拟器。

原因是模拟器创建了一个未桥接的私有虚拟网络(10.0.2.0),因此您必须转发端口才能访问它。

【讨论】:

  • 它给了我这个错误。原因:java.net.ConnectException:在 java.net.PlainSocketImpl.socketConnect(Native Method) 处拒绝连接(拒绝连接)
  • 它成功了,之前我使用的是本地主机 IP 而不是 localhost。您能否单行解释一下为什么我必须进行此转发。非常感谢?
  • 另一个问题是我无法在 Profiler 中看到网络数据,我已经编辑了有关此问题的原始帖子
最近更新 更多