Socket 客戶端與服務端通信及控制檯亂碼問題解決

此片博客是根據慕課網Socket網絡編程進階與實戰的學習記錄。

簡介

Socket是網絡上運行的兩個程序間雙向通訊的一端,它既可以接受請求,也可以發送請求,利用它可以較爲方便的編寫網絡上數據的傳遞。在Java中,有專門的Socket類來處理用戶的請求和響應。利用Socket類的方法,就可以實現兩臺計算機之間的通訊。

如果想了解Socket通訊原理及三次握手請移步。

Client客戶端代碼實現。

 public static void main(String[] args) throws IOException {
        Socket socket = new Socket();
        /*超時時間*/
        socket.setSoTimeout(3000);
        /*連接本地   端口2000  超時時間3000*/
        socket.connect(new InetSocketAddress(InetAddress.getLocalHost(), 2000), 3000);
        System.out.printf("已發起服務器連接,並進入後續流程");
        System.out.printf("客戶端信息:" + socket.getLocalAddress() + "P:" + socket.getLocalPort());
        System.out.printf("服務器信息:" + socket.getInetAddress() + "P:" + socket.getPort());

        try {
            /*發送數據*/
            todo(socket);
        } catch (Exception e) {
            System.out.printf("異常關閉");
        }
        /*釋放資源*/
        socket.close();
        System.out.println("客戶端已退出~");
    }

    private static void todo(Socket client) throws IOException {
        /*鍵盤輸入*/
        InputStream in = System.in;
        BufferedReader inpu = new BufferedReader(new InputStreamReader(in));
        /*得到socket輸出流,轉換成打印流*/
        OutputStream outputStream = client.getOutputStream();
        PrintStream socketPrintStream = new PrintStream(outputStream);

        /*得到Soclet輸入流,轉換爲BufferedReader*/
        InputStream inputStream = client.getInputStream();
        BufferedReader socketBufferedReader = new BufferedReader(new InputStreamReader(inputStream));


        boolean flag = true;
        do {
            /*鍵盤讀取一行*/
            String str = inpu.readLine();
            /*發送到服務器*/
            socketPrintStream.println(str);
            /*從服務器讀取一行*/
            String echo = socketBufferedReader.readLine();
            if ("bye".equalsIgnoreCase(echo)) {
               flag = false;
            }else{
                System.out.println(echo);
            }

        } while (flag);

        /*釋放資源*/
        socketPrintStream.close();
        socketBufferedReader.close();

    }

Server服務端代碼實現。

public static void main(String[] args) throws IOException {

        /**
         *  port:指定的端口號
         */
        ServerSocket serverSocket = new ServerSocket(2000);

        System.out.printf("服務器準備就緒~");
        System.out.printf("服務器信息:" +serverSocket.getInetAddress());


        /*等待客戶端連接*/
        for (;;){
            /*套接字 得到客戶端*/
            Socket client = serverSocket.accept();
            ClientHandler clientHandler = new ClientHandler(client);
            clientHandler.start();

        }
    }

    private  static class ClientHandler extends  Thread{
        private Socket socket;
        private boolean flag = true;
        ClientHandler(Socket socket){
            this.socket = socket;
        }

        @Override
        public void run() {
            super.run();
            System.out.println("新客戶端連接:" +socket.getInetAddress()+" P:"+socket.getPort());

            try {
                PrintStream socketOutPut = new PrintStream(socket.getOutputStream());
                BufferedReader socketInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                do {
                      String str = socketInput.readLine();

                      if("bye".equalsIgnoreCase(str)){
                          flag =false;
                          /*回送*/
                          socketOutPut.println("bye");
                      }else{
                          /*打印數據長度,並回送*/
                          System.out.println(str);
//                          System.out.println(getEncoding("編碼格式爲:"+str));
                          socketOutPut.println("字符長度:"+str.length());
                      }
                }while (flag);
             }catch (Exception e){
                System.out.println("連接異常斷開");
            }finally {
                /*連接關閉*/
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.out.println("客戶端已退出:"+ socket.getInetAddress()+" P:"+socket.getPort());
            }
        }
    }

至此我們就實現了客戶端和服務端的通信。

可以看到我們雖然實現了客戶端和服務端的通信但是會有亂碼這裏提供一種解決方案 

方案來源

結尾追加

-Dfile.encoding=UTF-8

並且在你的builder.gradle中添加

tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}

這樣就可以解決亂碼的問題了!

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