Android入門筆記 - 網路通訊 - Socket

來源:互聯網
上載者:User

Android入門筆記 - 網路通訊 - Socket

今天來學習一下android中通訊方式中的socket。上兩次我們分別使用了HttpURLConnection , 和 HttpClient來實現通訊,他們都是在使用HTTP協議,Socket被稱為通訊端,使用的協議有TCP和UDP,TCP和UDP的區別在於TCP是可靠穩定的,內建容錯處理等優點,所以效率要低一點。然後UDP就不那麼穩定了,當使用UDP發送資料的時候,每次send,那麼socket只管send,不會管send之後對方是否收到,是否順序正確,所以UDP被稱為不穩定的傳輸,但是其效率卻很高,因為做的事情很簡單。

今天我們學習socket是使用tcp協議,在android中使用socket其實就是使用java中的socket,看應用的包 java.net.*; 就知道。

 

我們來完成一個小的區域網路聊天的程式,包含一個伺服器,android應用作為用戶端,一台手機發送資訊後,伺服器會轉寄給其他手機,很簡單。代碼比較多,後面附上,我們先來看怎麼使用socket。

 

用戶端:

用戶端Socket使用步驟:

(1)Socket mSocket = new Socket( SERVER_IP, SERVER_PORT); // 兩個參數分別為伺服器ip地址,和伺服器監聽的連接埠號碼

(2)BufferedReader mBufferReader = new BufferedReader(new InputStreamReader( mSocket.getInputStream())); // 通過socket.getInputStream() 可以得到輸入資料流,可從socket擷取伺服器發送的資料。為了能一行一行讀取,我們將其轉化為 BufferReader,可以使用BufferReader.readLine() 一行一行得去取等待在socket上的資料。

(3)PrintWriter mPrintWriter = new PrintWriter(mSocket.getOutputStream(), true); // 通過socket.getOutputStream() 可以得到輸入資料流,就可以通過socket向伺服器發送資料, 這裡需要套上 PrintWriter 標準的介面,就可以使用 mPrintWriter.println(“ ... ),直接發送資料。

(4)使用完後中斷連線。

我們來看一看執行個體:

 

mSocket = new Socket(SERVER_IP, SERVER_POART);mBufferReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));mPrintWriter = new PrintWriter(mSocket.getOutputStream(), true);
如果沒有報 Exception那就表示連結的伺服器已經成功,這時就可以使用 mBufferReader和 mPrintWrinter 來實現資料的收發。

 

讀取資料:

 

                while (true) {                    if (null != (mStrMsg = mBufferReader.readLine())) {                        mStrMsg += ;                        if(mStrMsg.trim().equals(exit)){                            mHandler.sendMessage(mHandler.obtainMessage(2));                            return ;                        }                        mHandler.sendMessage(mHandler.obtainMessage(0));                    }                }
發送資料:

 

 

    private View.OnClickListener sendListener = new View.OnClickListener() {        @Override        public void onClick(View v) {            String str = mEtMessage.getText().toString().trim();            if(mPrintWriter == null){                showToast(請先串連伺服器!);                return ;            }            mPrintWriter.println(str);            mPrintWriter.flush();            mEtMessage.setText();        }    };
中斷連線:

 

 

showToast(中斷連線);    try {mBufferReader.close();mPrintWriter.close();mSocket.close();mSocket = null;if (mGetMessageThread != null) {    mGetMessageThread = null;}     } catch (IOException e) {          e.printStackTrace();     }

 

服務端:

在服務端我們需要有一個ServerSocket,這是用來接收串連請求的,當每接收到一個一個請求後就會返回一個Socket通訊端,就可以使用這個通訊端與用戶端通訊。注意:伺服器端應該是一直運行,且可以接收很多串連的程式,伺服器程式一定不能被關閉或者崩掉,所以在設計伺服器的時候要考慮很多很多事情,我們這裡只是簡單的處理收到用戶端請求串連,然後將其加入到list當中,如果收到訊息,就將收到的訊息轉寄給列表中其他所有socket,很簡單的處理。

使用步驟:

(1)ServerSocket mServerSocket = new ServerSocket(SERVERPORT); // 建立監聽串連ServerSocket

(2)不停監聽 mServerSocket, 使用accept() 接收串連,如果偵測到串連,就啟動一個線程,將傳回值socket傳入,那麼每個線程就對應一個用戶端,可以與用戶端通訊了。

(3)接下來就是 每個線程如果收到資料,就需要將訊息轉寄給 客戶單列表中所有其他使用者。

(4)用戶端取消連結後,清除客戶socket資訊。

啟動監聽串連,並啟動一個線程池,當監聽到串連請求時建立啟動線程,並放入到線程池中運行:

        try {            mServerSocket = new ServerSocket(SERVERPORT);            mExecutorService = Executors.newCachedThreadPool();            System.out.println(Server Start...);            Socket client = null;            while (true) {                client = mServerSocket.accept();                mClientList.add(client);                mExecutorService.execute(new ThreadServer(client));            }        } catch (IOException e) {            e.printStackTrace();        }
線程中接收訊息,以及轉寄訊息:

 

 

    private class ThreadServer implements Runnable {        private Socket mClient;        private BufferedReader mBufferedReader;        private PrintWriter mPrintWriter;        private String mStrMsg;        public ThreadServer(Socket client) throws IOException {            this.mClient = client;            mBufferedReader = new BufferedReader(new InputStreamReader(                    mClient.getInputStream()));            mStrMsg = usr: + this.mClient.getInetAddress() +  connected                    + ,total: + mClientList.size();            sendMessage(mStrMsg);        }        private void sendMessage(String msg) throws IOException {            System.out.println(msg);            for (Socket client : mClientList) {                mPrintWriter = new PrintWriter(client.getOutputStream(), true);                mPrintWriter.println(msg);            }        }        @Override        public void run() {            try {                while (null != (mStrMsg = mBufferedReader.readLine())) {                    if (mStrMsg.trim().equals(exit)) {                        mStrMsg = user: + mClient.getInetAddress() +  exit!                                + total: + (mClientList.size() - 1);                        sendMessage(mStrMsg);                        mPrintWriter = new PrintWriter(                                mClient.getOutputStream(), true);                        mPrintWriter.println(exit);                        mBufferedReader.close();                        mPrintWriter.close();                        mClientList.remove(mClient);                        mClient.close();                        break;                    } else {                        mStrMsg = mClient.getInetAddress() + : + mStrMsg;                        sendMessage(mStrMsg);                    }                }            } catch (SocketException e) {                // e.printStackTrace();            } catch (IOException e) {                e.printStackTrace();            }        }    }

 

 

如果沒有網路基礎,這個理解起來還是有點複雜的,下面貼了項目代碼,大家自己去體會一下吧,使用socket其實很簡單,主要是邏輯處理。

這裡有幾點需要注意的:

(1)android2.3之後不能再UI主線程中調用網路請求,會直接崩潰,所以需要使用handler來發送訊息處理

(2)執行個體代碼放在你的機子上不一定能使用,SERVER_IP為電腦在區域網路的本機地址,需要自己修改。 android用戶端需要連上電腦,這樣用戶端就能找到伺服器了。

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.