【问题标题】:Connecting a socket with static IP on a WiFi network while mobile data is turned on开启移动数据时,在 WiFi 网络上使用静态 IP 连接套接字
【发布时间】:2020-01-28 21:08:02
【问题描述】:

我需要在 Android 中设计一个应用程序,该应用程序需要手机通过打开一个套接字来连接到服务器。当我刚刚连接到特定的 wifi 网络(即托管服务器的 Wifi 网络)时,我能够实现这一点,但是在我连接到 wifi 网络和移动数据网络的情况下,我得到一个套接字异常抛出为android 尝试通过移动网络连接套接字

当设备刚刚连接到需要建立套接字连接的设备的wifi时,我已经能够连接设备

  static class StartTCPconnection extends AsyncTask<Void, Void, Void> {
    final WeakReference<RemoteActivity> activity;

    StartTCPconnection(WeakReference<RemoteActivity> activity) {
        this.activity = activity;
    }


    @Override
    protected Void doInBackground(Void... voids) {
        try {
            socket = new Socket("192.168.4.1", 900);
            Log.d(TAG, "is socket connected ? ...." + socket.isConnected());
            printWriter = new PrintWriter(socket.getOutputStream(), true);
            Log.i(TAG, "Checking if socket is really connected " + (socket.getLocalSocketAddress()));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        if (socket != null) {
            if (socket.isConnected() && isWifi) {
                Log.d(TAG, "onPostExecute: " + socket.isConnected());
                Toast.makeText(activity.get(), "Connection established", Toast.LENGTH_SHORT).show();
                Log.e(TAG, "onPostExecute: " + activity.get().getSharedPreferences(Constants.REMOTE_SWITCH_SHARED_PREFERENCE, Context.MODE_PRIVATE).getInt(Constants.REMOTE_SWITCH_KEY, 99));
                if (activity.get().getSharedPreferences(Constants.REMOTE_SWITCH_SHARED_PREFERENCE, Context.MODE_PRIVATE).getInt(Constants.REMOTE_SWITCH_KEY, 1) == 1) {
                    activity.get().joyStickFragment.checkSocketInstance(socket);
                    activity.get().joyStickFragment.changeUIForConnect();
                } else if (activity.get().getSharedPreferences(Constants.REMOTE_SWITCH_SHARED_PREFERENCE, Context.MODE_PRIVATE).getInt(Constants.REMOTE_SWITCH_KEY, 1) == 2) {
                    Log.e(TAG, "onPostExecute:Check  " + socket.isConnected());
                    activity.get().buttonRemoteFragment.checkSocketInstance(socket);
                    activity.get().buttonRemoteFragment.changeUIForConnect();
                }
                activity.get().connectionIndicatorImage.setImageResource(R.drawable.avishkaar_logo_on);
                activity.get().wifiIndicator.setImageResource(R.drawable.wifi_connected_icon);
            }

        } else {
            //   Toast.makeText(activity.get(), "Wrong Wifi Network connected", Toast.LENGTH_SHORT).show();
        }

    }
}

如果唯一可用的网络是设备的 WiFi 并且移动网络已关闭,上述代码会将我连接到套接字

【问题讨论】:

    标签: android sockets wifi


    【解决方案1】:

    从编程的角度来看,连接到本地网络中的服务器和不在本地网络中的服务器之间并没有什么特别之处。唯一的要求是服务器实际上首先是可访问的,即不在私有的无法访问的网络中并且没有被防火墙或类似的阻止。当然,服务器的公共可达地址在程序中被用作目的地。

            socket = new Socket("192.168.4.1", 900);
    

    192.168.4.1 是private network 中的地址。这意味着无法从 Internet 访问它,这也意味着如果您使用移动数据连接或在不同网络(如公共热点)中使用 wifi,则无法访问它。

    要从该专用网络外部建立连接,服务器必须可以从该网络外部访问,即需要有一个公共的可路由 IP 地址。如果服务器在一些典型的家庭网络中,这可以通过路由器中的port forwarding 来实现。对于较大的设置,此类服务器位于可通过 Internet 直接访问的数据中心或(作为这种特殊情况)在 cloud 中。

    【讨论】:

    • 我明白...它是一种物联网设备,通过形成自己的AP来工作。我想知道的是,是否有一种方法可以让 android 设备连接到它而无需关闭移动数据,我现在必须这样做才能连接到它。
    • @FaizanMir:再次:您使用私有 IP 地址作为访问系统的目的地,并且该地址无法从 Internet 访问(因为它是私有 IP 地址而不是公共 IP 地址)。您首先需要让系统在 Internet 上可用,然后使用系统在 Internet 上的 IP 地址 - 而不是它在本地网络上的 IP 地址。只要设备提供的唯一连接是通过其自己的 AP,就无法从 Internet 访问它。所以你必须想办法把它集成到你现有的网络中,然后添加端口转发。
    • 我明白了
    猜你喜欢
    • 2017-03-11
    • 1970-01-01
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多