1. 程式人生 > >TCP/IP協議Socket通訊案例演示

TCP/IP協議Socket通訊案例演示

在伺服器端建立ServerScoket物件,並繫結埠號,用來讓客戶單進行訪問,客戶端建立Socket物件,繫結主機名(由於演示案例是在同一臺電腦上進行,所以主機名用了"localhost")和埠號,伺服器端監聽客戶單,通過輸入流讀取客戶端傳送的請求,輸出流相應客戶端請求。客戶端通過輸出流向伺服器端傳送請求,輸出流讀取伺服器端相應資訊。為了便於在控制條展示資訊,輸出流都用了列印流進行包裝。

伺服器端程式碼

/**
 * 服務端
 */
public class Server {
    public static void main(String[] args) {
        //建立伺服器端ServerSocket
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            Socket socket = null;
            System.out.println("###伺服器即將啟動###");
            int count = 0;
            while (true) {
                //監聽客戶端請求
                socket = serverSocket.accept();

                //啟動執行緒接收客戶端請求
                ServerThread serverThread = new ServerThread(socket);
                serverThread.start();
                count++;
                System.out.println("客戶端數量:" + count);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

伺服器實際情況是永遠不關閉,並且可以相應多個客戶端的請求,這裡用死迴圈和多執行緒進行模擬。

public class ServerThread extends Thread {

    Socket socket = null;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        InputStream is = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        OutputStream os = null;
        PrintWriter pw = null;
        try {
            //獲取輸入流讀取客戶端傳送的請求
            is = socket.getInputStream();

            //轉換為字元流幷包裝為高效輸入流
            isr = new InputStreamReader(is);
            br = new BufferedReader(isr);

            String info = null;
            while ((info = br.readLine()) != null) {
                System.out.println("我是伺服器,客戶端說:" + info);
            }
            socket.shutdownInput();

            //獲得輸出流,相應客戶端請求
            os = socket.getOutputStream();
            //為了在控制檯顯示資訊,這裡轉換為列印流
            pw = new PrintWriter(os);
            pw.write("伺服器端接收到客戶端請求");
            pw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (br != null) {
                    br.close();
                }
                if (isr != null) {
                    isr.close();
                }
                if (is != null) {
                    is.close();
                }
                if (pw != null) {
                    pw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

客戶端程式碼

/**
 * 客戶端
 */
public class Client {
    public static void main(String[] args) {
        try {
            //建立客戶端Socket,指定主機名和埠號
            Socket socket = new Socket("localhost", 8888);
            //獲得輸出流
            OutputStream os = socket.getOutputStream();
            //轉換為列印輸出流
            PrintWriter pw = new PrintWriter(os);

            pw.write("使用者名稱:admin,  密碼:789");
            pw.flush();
            socket.shutdownOutput();

            //獲得輸入流接收伺服器端相應內容
            InputStream is = socket.getInputStream();
            InputStreamReader ist = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(ist);

            String data = null;
            while ((data = br.readLine()) != null) {
                System.out.println("伺服器說:" + data);
            }

            //關閉流和資源
            is.close();
            ist.close();
            br.close();
            br.close();
            pw.close();
            os.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

結果展示:

每請求一次,客戶端資訊更改一次,用來模擬多使用者操作

注意:必須先啟動伺服器端,再啟動客戶端

啟動伺服器端資訊展示

啟動客戶端:

這時客戶端會向伺服器端傳送請求,伺服器端做出相應的相應

在看伺服器端控制檯

伺服器端接收到了客戶端的請求資訊

更改客戶端請求資訊,模擬多客戶端請求