Android 在打开移动数据时,在WiFi网络上连接具有静态IP的插座

Android 在打开移动数据时,在WiFi网络上连接具有静态IP的插座,android,sockets,wifi,Android,Sockets,Wifi,我被要求用Android设计一个应用程序,它要求手机通过打开一个插座连接到服务器。当我刚刚连接到特定的wifi网络(即承载服务器的wifi网络)时,我能够实现这一点,但当我连接到wifi网络和移动数据网络时,当android尝试通过移动网络连接套接字时,我会引发套接字异常 我已经能够在设备刚刚连接到需要建立套接字连接的设备的wifi时连接该设备 static class StartTCPconnection extends AsyncTask<Void, Void, Void>

我被要求用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();
        }

    }
}
静态类StartTCPconnection扩展异步任务{
最终参考活动;
StartTCPconnection(WeakReference活动){
这个。活动=活动;
}
@凌驾
受保护的空位背景(空位…空位){
试一试{
插座=新插座(“192.168.4.1”,900);
Log.d(标记“是否已连接套接字?”…“+socket.isConnected());
printWriter=新的printWriter(socket.getOutputStream(),true);
Log.i(标记“检查套接字是否真正连接”+(socket.getLocalSocketAddress());
}捕获(IOE异常){
e、 printStackTrace();
}
返回null;
}
@凌驾
受保护的void onPostExecute(void避免){
super.onPostExecute(避免);
if(套接字!=null){
if(socket.isConnected()&&isWifi){
Log.d(标记“onPostExecute:+socket.isConnected());
Toast.makeText(activity.get(),“已建立连接”,Toast.LENGTH_SHORT.show();
Log.e(标记“onPostExecute:”+activity.get().getSharedReferences(Constants.REMOTE\u SWITCH\u SHARED\u首选项,Context.MODE\u PRIVATE).getInt(Constants.REMOTE\u SWITCH\u KEY,99));
if(activity.get().getSharedReferences(Constants.REMOTE\u SWITCH\u SHARED\u首选项,Context.MODE\u PRIVATE).getInt(Constants.REMOTE\u SWITCH\u KEY,1)==1){
activity.get().joyStickFragment.checkSocketInstance(套接字);
activity.get().joyStickFragment.changeUIForConnect();
}else if(activity.get().getSharedReferences(Constants.REMOTE\u SWITCH\u SHARED\u首选项,Context.MODE\u PRIVATE).getInt(Constants.REMOTE\u SWITCH\u KEY,1)=2){
Log.e(标记“onPostExecute:Check”+socket.isConnected());
activity.get().buttonRemoteFragment.checkSocketInstance(套接字);
activity.get().buttonRemoteFragment.changeUIForConnect();
}
activity.get().connectionIndicatorImage.setImageResource(R.drawable.avishkaar_logo_on);
activity.get().wifiIndicator.setImageResource(R.drawable.wifi\u connected\u图标);
}
}否则{
//Toast.makeText(activity.get(),“连接了错误的Wifi网络”,Toast.LENGTH\u SHORT.show();
}
}
}

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

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

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


要使从该专用网络外部的连接成为可能,服务器必须能够从该网络外部访问,即需要具有公共可路由IP地址。如果服务器位于某个典型的家庭网络中,这可以通过路由器中的连接来实现。对于较大的设置,此类服务器位于可直接从internet访问的数据中心,或者(作为特例)位于。

我了解。。。它是一种物联网设备,通过形成自己的AP来工作。我想知道的是,是否有一种方法可以让android设备连接到它,而无需关闭移动数据,我现在必须这样做才能连接到它。@FaizanMir:再次说明:您使用的是一个专用IP地址作为访问系统的目的地,而这个地址无法从internet访问(因为它是一个私有而非公共IP地址)。首先,您需要让系统在internet上可用,然后使用系统在internet上的IP地址,而不是在本地网络上的IP地址。只要设备提供的唯一连接是通过其自己的AP,则无法从internet访问。因此,您必须找到一种方法将其集成到网络中你的现有网络,然后添加端口转发。我明白吗
        socket = new Socket("192.168.4.1", 900);