很难理解 wifi 连接是如何工作的

Hard time understanding how wifi connection work

我有一个应用程序监听指定的 ip 和端口。我明白了如何连接,如何接收数据。

事情是这样的:

这是我用来获取数据的class:

public final class MyClientTask extends AsyncTask<Void, Void, Void> {
    BufferedReader br = null;
    String dstAddress;
    int dstPort;
    String response = "";

    public MyClientTask(String addr, int port){
        dstAddress = addr;
        dstPort = port;
    }

    @Override
    protected Void doInBackground(Void... arg0) {
        Socket socket = null;
        try {
            socket = new Socket(dstAddress, dstPort);

            ByteArrayOutputStream byteArrayOutputStream =
                    new ByteArrayOutputStream(1024);
            byte[] buffer = new byte[1024];

            //Instanciation de l'inputStreamReader
            InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream());

            // creation nouveau bufferreader
            br = new BufferedReader(inputStreamReader);

            StringBuilder msgBuilder = new StringBuilder();
            // on évite String = String + char qui fait des créations de builders automatiques en java.
            boolean ended = false;
            while (!ended) {
                int nextChar = inputStreamReader.read();
                if (nextChar == -1) {
                    ended = true; // <= fin du stream
                } else if (nextChar == 03) {

                    String maChaine="";
                    // fin du message
                    maChaine = msgBuilder.toString();

                    //récupération du char après <STX>
                    Character nbChamps = maChaine.charAt(1);
                    //test pour savoir si c'est une alerte
                    if(nbChamps == '7'){
                        //insertion de l'alerte dans la BDD
                        BDDAlerte.insertAlerte1(maChaine);
                        //creation de la notif
                        createNotification();

                    }
                    //ici les tests splits pour le nombre de champs et inserer dans BdD ou faire ce qu'il faut

                    //suppVieillesAlertes();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            //find listview to populate
                            final ListView lvItems = (ListView)findViewById(R.id.listView1);
                            //setup cursor adapter using Cursor from last step
                            final AlerteAdapter todoAdapter = new AlerteAdapter(getBaseContext(), BDDAlerte.getAllRows(),0);

                            lvItems.setAdapter(todoAdapter);
                        }
                    });
                    // réinitialisation du builder
                    msgBuilder.setLength(0);
                } else {
                    msgBuilder.append((char)nextChar);
                }
            }
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            response = "UnknownHostException: " + e.toString();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            response = "IOException: " + e.toString();
        }
        finally{
            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

我的退出按钮位于 onOptionsItemSelected 应用程序的菜单中。

如果我没有提供所有数据,我是来澄清事情的。

西蒙

private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager 
      = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

构造套接字前,应先检查网络状态

如果在读取数据时抛出io异常,则意味着连接丢失。

您可以定义一个布尔字段 "running",初始为 true,当应用程序退出时将其设置为 false,在您的 while 循环中检查它的值,如下所示:

 while (!ended&&running) {
            int nextChar = inputStreamReader.read();
            if (nextChar == -1) {
                ended = true; // <= fin du stream
            } 
// ......
}

首先创建一个单独的 class 来检查连接并通过调用方法来设置条件,而不是仅对套接字进行进一步处理..

public class 移动连接 {

    public static NetworkInfo getNetworkInfo(Context context) {

        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        return cm.getActiveNetworkInfo();
    }

    public static boolean isConnected(Context context) {

        NetworkInfo info = MobileConnectivity.getNetworkInfo(context);
        return (info != null && info.isConnected());
    }

    public static boolean isConnectedWifi(Context context) {

        NetworkInfo info = MobileConnectivity.getNetworkInfo(context);
        return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI);
    }

    public static boolean isConnectedMobile(Context context) {
        NetworkInfo info = MobileConnectivity.getNetworkInfo(context);
        return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE);
    }

    public static boolean isConnectedFast(Context context) {
        NetworkInfo info = MobileConnectivity.getNetworkInfo(context);
        return (info != null && info.isConnected()
                && MobileConnectivity.isConnectionFast(info.getType(), info.getSubtype()));
    }

    public static boolean isConnectionFast(int type, int subType) {
        if (type == ConnectivityManager.TYPE_WIFI) {
            return true;
        } else if (type == ConnectivityManager.TYPE_MOBILE) {
            switch (subType) {
            case TelephonyManager.NETWORK_TYPE_1xRTT:
                return false; // ~ 50-100 kbps
            case TelephonyManager.NETWORK_TYPE_CDMA:
                return false; // ~ 14-64 kbps
            case TelephonyManager.NETWORK_TYPE_EDGE:
                return false; // ~ 50-100 kbps
            case TelephonyManager.NETWORK_TYPE_EVDO_0:
                return true; // ~ 400-1000 kbps
            case TelephonyManager.NETWORK_TYPE_EVDO_A:
                return true; // ~ 600-1400 kbps
            case TelephonyManager.NETWORK_TYPE_GPRS:
                return false; // ~ 100 kbps
            case TelephonyManager.NETWORK_TYPE_HSDPA:
                return true; // ~ 2-14 Mbps
            case TelephonyManager.NETWORK_TYPE_HSPA:
                return true; // ~ 700-1700 kbps
            case TelephonyManager.NETWORK_TYPE_HSUPA:
                return true; // ~ 1-23 Mbps
            case TelephonyManager.NETWORK_TYPE_UMTS:
                return true; // ~ 400-7000 kbps
            /*
             * Above API level 7, make sure to set android:targetSdkVersion to
             * appropriate level to use these
             */
            case TelephonyManager.NETWORK_TYPE_EHRPD: // API level 11
                return true; // ~ 1-2 Mbps
            case TelephonyManager.NETWORK_TYPE_EVDO_B: // API level 9
                return true; // ~ 5 Mbps
            case TelephonyManager.NETWORK_TYPE_HSPAP: // API level 13
                return true; // ~ 10-20 Mbps
            case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8
                return false; // ~25 kbps
            case TelephonyManager.NETWORK_TYPE_LTE: // API level 11
                return true; // ~ 10+ Mbps
            // Unknown
            case TelephonyManager.NETWORK_TYPE_UNKNOWN:
            default:
                return false;
            }
        } else {
            return false;
        }
    }