Socket傳輸案例(上)----服務端

這篇博客呢主要是兩個手機進行 Socket 通信案例的分析

(話說老孃也算寫了幾篇博客,爲什麼訪問量就是少的可憐呢……)

首先是這個案例可以實現什麼:
它包含兩個工程,一個服務端,一個客戶端,服務端的工程裏面有個按鈕,是打開服務端鏈接,客戶端有兩個按鈕,一個是鏈接服務端,一個是發送數據

什麼是 TCP/IP 協議,什麼是 Socket ???

網絡由下往上分爲:
物理層–
數據鏈路層–
網絡層– IP協議
傳輸層– TCP協議
會話層–
表示層和應用層– HTTP協議
TCP/TP協議簡稱 網絡傳輸層,主要用來傳輸數據

爲了區別不同的應用程序進程和連接,許多計算機操作系統爲應用程序與 TCP/IP 協議交互提供了套接字( Socket )接口。應用層可以和傳輸層通過 Socket 接口,區分來自不同應用程序進程或網絡連接的通信,實現數據傳輸的併發服務。

這個大神講的挺清楚的:http://www.cnblogs.com/iOS-mt/p/4264675.html

爲了讓APP正確運行,必須要保證兩個設備的網絡屬於同一個網端 (連接在了同一個WiFi上面)

服務端一共做了兩件事:
1.打開服務端等待客戶端鏈接
2.接收客戶端信息並反饋給客戶端信息

這兩個功能的實現我都把它封裝到兩個內部類裏面了

下面是這個工程的步驟

1.創建服務端 Socket 監聽服務端的鏈接

等待客戶端的鏈接是一個耗時操作,所以要放到子線程

    class ServerSocketThread extends Thread {
        @Override
        public void run() {
            try {
            //創建服務端Socket
                ServerSocket serverSocket = new ServerSocket();
                //綁定客戶端(因爲是在同一個機子上訪問,所以IP地址一樣,直接是127.0.0.1)
                serverSocket.bind(new InetSocketAddress("10.232.9.241", 1234));//服務端的IP地址
                //一直等待客戶端鏈接
                while (true) {
                    Log.e("TAG", "server_wait");
                    //鏈接客戶端
                    Socket socket = serverSocket.accept();
                    //這是一個監聽客戶端發送信息,並向客戶端反饋的方法,(後面講到)
                    connected(socket);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

步驟:
創建一個serverSocket 爲它綁定IP地址和端口號,IP地址那一行需要更改
不斷地while循環 監聽客戶端的鏈接
注意:創建SeverSocket的時候IP地址要是服務端的IP地址(我在這裏跌倒過…)

最後是可以打印出以下的log日誌的:

2.接收客戶端的信息並向客戶端反饋
同樣這裏要開啓一個子線程,因爲要不斷地接收客戶端的信息,所以這個也定義在內部類中了

 class ConnectThread extends Thread {
        Socket socket;//得到連接的客戶端的Socket
        InputStream in = null;
        OutputStream out = null;

        public ConnectThread(Socket socket) {
            this.socket = socket;
            try {
                in = socket.getInputStream();
                out = socket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }


        }
        @Override
        public void run() {
            byte[] buffer = new byte[1024];//字節數組承載讀到的字節
            int bytes ;
            //等待另一端發送的數據
            try {
                while ((bytes = in.read(buffer)) != -1) {
                    Log.e("TAG", "server_read:" + new String(buffer, 0, bytes));
                    String data = "server_read_success";
                    write(data.getBytes());//向客戶端寫入反饋的方法
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

因爲要接收和向客戶端發送信息所以必須得到客戶端 socket 對象的輸入輸出流,所以在構造方法中要傳入和服務端結合的客戶端 socket
這樣就可以讀到客戶端發來的信息繫了

那麼怎麼給客戶端一個反饋呢 ???—-就是向客戶端發出信息

我把這個也放到了和服務端通信的內部類中了

//向另一端寫數據的操作
        public void write(byte[] buffer) {
            try {
                out.write(buffer);
                Log.e("TAG", "server_write  " + new String(buffer));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

最後是關閉流,只需要關閉 socket 即可

//關閉的方法
        public void cancle() {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

這個通信類就寫完了,裏面包含開啓
子線程(run方法中)不斷地接收客戶端發來的信息
向客戶端寫入信息
關閉流的操作

3.connected(Socket socket);方法的實現
在上面第一個內部類綁定好客戶端後有個鏈接客戶端的方法,這個方法主要是做對客戶端消息的監聽和反饋,對!就是對上面第二個類的實例化之類的操作

private void connected(Socket socket) {
        if (connectThread != null) {
            connectThread.cancle();
            connectThread = null;
        }
        connectThread = new ConnectThread(socket);
        connectThread.start();
        Log.e("TAG", "connect success");
    }

把這個方法放到第一個綁定客戶端的類裏面就行了

最後最後!! 別忘了 new ServerSocketThread().start();

源碼在這裏 :

戳我!! 戳我呀!!!!

謝謝觀看~

這裏寫圖片描述

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