一個 Java 的 Socket 服務器和客戶端通信的例子


  一個 HelloWord 級別的 Java Socket 通信的例子。通訊過程:
  先啟動 Server 端,進入一個死循環以便一直監聽某端口是否有連接請求。然后運行 Client 端,客戶端發出連接請求,服務端監聽到這次請求后向客戶端發回接受消息,連接建立,啟動一個線程去處理這次請求,然后繼續死循環監聽其他請求。客戶端輸入字符串后按回車鍵,向服務器發送數據。服務器讀取數據后回復客戶端數據。這次請求處理完畢,啟動的線程消亡。如果客戶端接收到 "OK" 之外的返回數據,會再次發送連接請求並發送數據,服務器會為這次連接再次啟動一個線程來進行響應。。。直到當客戶端接收到的返回數據為 "OK" 時,客戶端退出。

服務端源代碼:

public class Server {  
    public static final int PORT = 12345;//監聽的端口號     
      
    public static void main(String[] args) {    
        System.out.println("服務器啟動...\n");    
        Server server = new Server();    
        server.init();    
    }    
    
    public void init() {    
        try {    
            ServerSocket serverSocket = new ServerSocket(PORT);    
            while (true) {    
                // 一旦有堵塞, 則表示服務器與客戶端獲得了連接    
                Socket client = serverSocket.accept();    
                // 處理這次連接    
                new HandlerThread(client);    
            }    
        } catch (Exception e) {    
            System.out.println("服務器異常: " + e.getMessage());    
        }    
    }    
    
    private class HandlerThread implements Runnable {    
        private Socket socket;    
        public HandlerThread(Socket client) {    
            socket = client;    
            new Thread(this).start();    
        }    
    
        public void run() {    
            try {    
                // 讀取客戶端數據    
                DataInputStream input = new DataInputStream(socket.getInputStream());  
                String clientInputStr = input.readUTF();//這里要注意和客戶端輸出流的寫方法對應,否則會拋 EOFException  
                // 處理客戶端數據    
                System.out.println("客戶端發過來的內容:" + clientInputStr);    
    
                // 向客戶端回復信息    
                DataOutputStream out = new DataOutputStream(socket.getOutputStream());    
                System.out.print("請輸入:\t");    
                // 發送鍵盤輸入的一行    
                String s = new BufferedReader(new InputStreamReader(System.in)).readLine();    
                out.writeUTF(s);    
                  
                out.close();    
                input.close();    
            } catch (Exception e) {    
                System.out.println("服務器 run 異常: " + e.getMessage());    
            } finally {    
                if (socket != null) {    
                    try {    
                        socket.close();    
                    } catch (Exception e) {    
                        socket = null;    
                        System.out.println("服務端 finally 異常:" + e.getMessage());    
                    }    
                }    
            }   
        }    
    }    
}    

 

客戶端源代碼:

public class Client {  
    public static final String IP_ADDR = "localhost";//服務器地址   
    public static final int PORT = 12345;//服務器端口號    
      
    public static void main(String[] args) {    
        System.out.println("客戶端啟動...");    
        System.out.println("當接收到服務器端字符為 \"OK\" 的時候, 客戶端將終止\n");   
        while (true) {    
            Socket socket = null;  
            try {  
                //創建一個流套接字並將其連接到指定主機上的指定端口號  
                socket = new Socket(IP_ADDR, PORT);    
                    
                //讀取服務器端數據    
                DataInputStream input = new DataInputStream(socket.getInputStream());    
                //向服務器端發送數據    
                DataOutputStream out = new DataOutputStream(socket.getOutputStream());    
                System.out.print("請輸入: \t");    
                String str = new BufferedReader(new InputStreamReader(System.in)).readLine();    
                out.writeUTF(str);    
                    
                String ret = input.readUTF();     
                System.out.println("服務器端返回過來的是: " + ret);    
                // 如接收到 "OK" 則斷開連接    
                if ("OK".equals(ret)) {    
                    System.out.println("客戶端將關閉連接");    
                    Thread.sleep(500);    
                    break;    
                }    
                  
                out.close();  
                input.close();  
            } catch (Exception e) {  
                System.out.println("客戶端異常:" + e.getMessage());   
            } finally {  
                if (socket != null) {  
                    try {  
                        socket.close();  
                    } catch (IOException e) {  
                        socket = null;   
                        System.out.println("客戶端 finally 異常:" + e.getMessage());   
                    }  
                }  
            }  
        }    
    }    
}

 

  注意: Socket 輸出流寫數據方法是 writeUTF 時,輸入流讀取相關數據要用 readUTF。否則會拋 EOFException 異常。具體原因請參考文后鏈接。
參考資料:http://stackoverflow.com/questions/5489915/java-datainputstream-read-operations-throwing-exceptions

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM