Android Socket長連接的使用和封裝;

這次的項目JT/T 808協議使用Socket通訊,對原生的Socket研究了一下,把使用方法和心得寫一下;

這個時必須要加的權限:

<uses-permission android:name="android.permission.INTERNET" />

Android主線程中不允許做耗時操作,Socket需要放在子線程中;

1、創建Socket連接,拿到輸入輸出流:

    private Socket socket;
    private DataInputStream dis;
    private OutputStream out;
    /**
     * 創建socket客戶端
     */
    private void create() {
            if (socket == null) socket = new Socket();
            try {
                socket.connect(new InetSocketAddress(IP, Integer.valueOf(PORT)), 5 * 1000);
                if (socket.isConnected()) {
                    out = socket.getOutputStream();
                    InputStream in = socket.getInputStream();
                    dis = new DataInputStream(in);
                    String s = "服務器連接成功!";
                    Log.d(TAG, s);
                }
            } catch (IOException e) {
                e.printStackTrace();
                if (e instanceof SocketTimeoutException) {
//                    toastMsg("連接超時,正在重連");

                } else if (e instanceof NoRouteToHostException) {
//                    toastMsg("該地址不存在,請檢查");
                } else if (e instanceof ConnectException) {
//                    toastMsg("連接異常或被拒絕,請檢查");
                } else if (e instanceof SocketException){
//                    if (TextUtils.equals(e.getMessage(),"already connected"))
//                        toastMsg("當前已連接,請勿再次連接");
                }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

2、連接成功後發送消息:

    /**
     * 發送消息
     */
    public synchronized void sendMsg(byte[] msg) {
        try {
            if (null != out) {
                out.write(msg);
                out.flush();
            }
        } catch (Exception e) {
            //出現此異常說明Socker已經斷開連接 斷線重連
            if (e instanceof SocketException) {
                reconnectServer();
            }
            e.printStackTrace();
        }
    }

    /**
     * 重連tcp
     */
    private void reconnectServer() {
        try {
            socket = new Socket(IP, PORT);
            socket.setSoTimeout(5000);
            out = socket.getOutputStream();
            InputStream in = socket.getInputStream();
            dis = new DataInputStream(in);
            String s = "斷線重連服務器: " + IP + ":" + PORT + " 連接成功!";
            Log.d(TAG, s);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

3、接收消息,Socket在讀取消息時線程屬於堵塞狀態,連接成功後就可以直接調用接收消息的方法:

        while (true) {
            try {
                byte[] buff = new byte[1024];
                int len = dis.read(buff);
                byte[] data = Arrays.copyOfRange(buff, 0, len);
                Log.i(TAG, "run: "+ HexUtil.byte2HexStr(data));
            } catch (Exception e) {
                e.fillInStackTrace();
            }

        }

注意:很多的文章都寫着使用readLine方法讀取消息,如果使用 readLine()方法讀取消息時,只有遇到換行符纔會繼續讀取,不建議使用此方法讀取消息;

附:

下載一個“網絡調試助手”就可以開始調試了;

這個日誌輸入有點磕磣,哈哈;

代碼封裝了一下,在線程池中做的處理;

代碼下載:https://github.com/CuiChenbo/FastSocketClient

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章