Socket通訊

Socket通訊簡單點理解就是通訊雙方通過某個端口進行數據的相互傳輸,與常用的http的請求-響應方式不同,Socket通訊無需客戶端向服務器發送請求,然後服務器在響應,直接就是進行數據傳輸。

一、Socket的類型

Socket有兩種類型:
1、基於TCP協議傳輸數據的streamsocket;
2、基於UDP協議傳輸數據的datagramsocket。
傳輸過程如下:
這裏寫圖片描述
通常我們都使用TCP協議傳輸
這裏寫圖片描述
如上圖Socket也分爲服務器端和客戶端,實際上一臺機器既可以是服務端也可以是客戶端,而兩端 之間通過字節流傳輸數據

二、Socket的具體實現

這裏的實現基於TCP協議的方式
1、首先在服務端先創建一個工作線程類來處理數據

public class MessageRunnable implements Runnable{
    private Socket socket=null;
    public MessageRunnable(Socket socket){
        this.socket=socket;
    }
    @Override
    public void run() {
        try {
            //獲取輸入輸出流
            InputStream is=socket.getInputStream();
            OutputStream os=socket.getOutputStream();

            //把數據寫回客戶端
//          String toClientStr="稍等下..客服忙...";
//          os.write(toClientStr.getBytes("utf-8"));
//          os.flush();
            //停止socket輸出(半關閉狀態)
//          socket.shutdownOutput();

            //讀取客戶端數據
            BufferedReader bf=new BufferedReader(new InputStreamReader(is));
            String line=null;
            String dataFromClient="";
            while ((line=bf.readLine())!=null) {
                dataFromClient+=line;
            }
            System.out.println("來自客戶端:"+dataFromClient);
            socket.shutdownInput();
            os.write(dataFromClient.getBytes("utf-8"));
            os.flush();

            os.close();
            is.close();
            socket.close();
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

主要是獲取輸入輸出流的方法,輸入流就是外界接收過來的數據流,輸出流就是本地向外界發送的數據流

InputStream is=socket.getInputStream();
OutputStream os=socket.getOutputStream();

2、然後再主線程創建ServerSocket對象

ServerSocket service=new ServerSocket(SOCKET_PORT);

上面方法傳遞的參數是通訊的端口號
3、通過ServerSocket對象的accept的方法獲取來自客戶端的socket對象
如果有數據過來就往下執行,否則就處於堵塞狀態

while(true){
                //監聽客戶送發過來的信息
                Socket socket=service.accept();
                new Thread(new MessageRunnable(socket)).start();
}

4、在客戶端創建好Socket對象,因爲是網絡操作所以要授權和在子線程運行,所以這裏通過handle的消息機制來更新UI

//構造用於發送socket線程
    private class SocketThread extends Thread{
        String message;
        SocketThread(String messsage){
            this.message=messsage;
        }
        @Override
        public void run() {
            try {
                socket=new Socket();
                socket.connect(new InetSocketAddress("192.168.1.100",8888),5000);

                //獲取輸入輸出流
                InputStream is=socket.getInputStream();
                OutputStream os=socket.getOutputStream();
                BufferedReader bf=new BufferedReader(new InputStreamReader(is));
                os.write(message.getBytes("utf-8"));
                os.flush();

                String line=null;
                String buff="";
                while ((line=bf.readLine())!=null){
                    buff+=line+"\n";
                }
                //發消息用於展示界面
                Message msg=Message.obtain();
                msg.what=MESSAGE_FLAG;
                Bundle bundle=new Bundle();
                bundle.putString("text",buff);
                msg.setData(bundle);
                handler.sendMessage(msg);

                os.close();
                is.close();
                bf.close();
                socket.close();

            }catch (SocketTimeoutException e){
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

//處理子線程消息
    private Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if(msg.what==MESSAGE_FLAG){
                Bundle bundle=msg.getData();
                String message=bundle.getString("text");
                tvDisplay.append("Server說:"+message+"\n");
            }
            super.handleMessage(msg);
        }
    };

客戶端這邊通過connect方法連接到服務端的端口實現雙方的通訊

三、總結

Socket是對TCP(UDP)協議的應用,主要應用場景是實時通信、遊戲之類的要求網絡能快速回應而不像http協議那般要發送請求才會獲取響應,socket發生的網絡連接,端與端之間可以主動推送數據,使數據響應更爲及時,當然這樣長時間的實時響應是很耗電的,所以一般長時間沒有數據傳遞都會關閉連接。

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