【问题标题】:Establishing communication between an Android and a non-Android device在 Android 和非 Android 设备之间建立通信
【发布时间】:2014-07-02 05:29:00
【问题描述】:

我希望在两台设备之间建立通信,一台是 Android 设备,另一台是非 Android 设备。其他设备通过搜索套接字客户端来发挥作用,而设备本身则充当套接字服务器。它确实获得了一个 IP 地址和一个端口号,现在在我的应用程序中,我希望程序能够搜索空套接字,而且看起来,普通的套接字编程对此还不够好。我可能需要在其中包含 mDNS 或 NSD 之类的东西。

任何有提示的人,如何完成任务?

【问题讨论】:

    标签: android sockets communication


    【解决方案1】:

    编写 Android 服务器与标准 Java 实现没有太大区别。

     ServerSocket serverSocket = new ServerSocket(SERVERPORT);
     while (true) {
          Socket newClient = serverSocket.accept(); // block until new connection
          <IO with newClient>
     }
    

    至于 IO 部分:你可以做标准阻塞 IO,这可能会 要求你产生额外的线程,或者你可以使用Android nio API

    现在:

    serverSocket 代码必须在专用线程上运行

    如果您计划一个长期运行的服务器,您可能希望将它放在一个 专门的服务。由 Activity 直接产生的线程可能会被 Android 交换 在他们的活动移到后台之后。

    在这方面服务要好得多。但服务最终也会下降。

    因此,如果服务器对您的系统非常重要,您将需要一种方法 告诉 Android 在资源不足时不要杀死它。方法是声明你的服务 作为foreground service

    Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
            System.currentTimeMillis());
    Intent notificationIntent = new Intent(this, ExampleActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
    notification.setLatestEventInfo(this, getText(R.string.notification_title),
            getText(R.string.notification_message), pendingIntent);
    startForeground(ONGOING_NOTIFICATION_ID, notification);
    

    前台服务比标准服务更稳定,但不妨碍 Android 去 睡觉,当你睡觉时没有任何作用。如果你真的需要你的应用程序来防止设备进入睡眠状态, 您需要获得wake lock。唤醒锁在电池消耗方面非常昂贵。小心处理。

    至于客户端代码(我假设是 Java 客户端)——它可能看起来像这样:

    Socket socket = new Socket(serverAddr, ServerActivity.SERVERPORT);
    while (true) {
       PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
       <write to peer>
       socket.close();
    }
    

    最后一个棘手的问题:您必须找出一种传递服务器 IP 地址的方法 对其同行。请记住 - 这是移动设备和您使用的网络 可以定期更改。要获取服务器 IP 地址,请使用:

    String getDeviceIpAddr() {
        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
            NetworkInterface network = en.nextElement();
            for (Enumeration<InetAddress> addr = network.getInetAddresses(); addr.hasMoreElements();) {
                 InetAddress inetAddress = addr.nextElement();
                 if (!inetAddress.isLoopbackAddress()) {
                     return inetAddress.getHostAddress().toString();
                 }
            }
        }
    }
    

    您需要某种方式将其传递给服务器的客户端。许多人为此使用中继服务器。

    【讨论】:

    • 我实现了一个线程,一个异步任务类,用于套接字的工作。由于我正在尝试通过 wifi 进行通信,因此我通过 wifi 搜索打开的套接字,但没有用。它不工作!
    • 07-02 15:41:20.217: W/System.err(2614): java.net.SocketException: socket failed: EACCES (Permission denied)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    • 2012-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多