用ServerSocket 實現服務端與客戶端之間信息傳遞

ServerSocket

具體用法參考jdk:
http://tool.oschina.net/apidocs/apidoc?api=jdk_7u4


爲了方便理解ServerSocket
服務器與客戶端的關係以及數據的交換
請看下圖:

這裏寫圖片描述


下面直接演示ServerSocket實現的幾個功能:
一、 客戶端服務端發信息給服務端
二、模擬一個廣播電臺(服務端向客服端發送信息)
三、模擬一個對講機(半雙工模式)只能交替通話,不能同時通話
四、做一個木馬文件
五、客戶端發送一個命令到服務端,服務端接收之後,在服務器執行這個命令,並把執行的結果返回給客戶端

示例中所用到的java包:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

一、 客戶端服務端發信息給服務端

/**
 * ServerSocket 實現服務端與客戶端通訊
 * 
 * @author PeicongHe
 *
 */

public class ServerSocketDemo {
    /**
     * 步驟: 
     * 1 先創建一個服務端,端口號爲:8888
     * 2 等待客戶端連接 
     * 3 創建一個客戶端的輸入流(用於將信息發送給服務端) 
     * 4 服務端打印並顯示信息
     */
    public static void test1() {
        try {
            ServerSocket serverSocket = new ServerSocket(8888); // 創建一個服務端,監聽端口8888
            Socket socket = serverSocket.accept(); // 等待客戶端連接過來
            System.out.println("來客IP: " + socket.getInetAddress()); // 獲取來客的IP地址
            InputStream is = socket.getInputStream();// 客戶端的輸入流
            Scanner sc = new Scanner(is);
            String msg = "";
            while (sc.hasNextLine()) {
                msg = sc.nextLine();
                System.out.println(msg);
                if (msg.equals("exit")) {
                    System.out.println("我要退出!");
                    System.exit(0);
                }
            }
            sc.close();
            is.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public Static void main(String[] args){
        test1();
    }
}

這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述


/**
     * 增加自動回覆功能 
     * 步驟: 
     *  1 在獲取客戶端輸入流前添加一個客戶端輸出流(用於輸出自動回覆內容)
     *  2 打印輸出流信息
     *  3  刷新打印
     */
    public static void test2() {
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            Socket socket = serverSocket.accept();
            System.out.println("來客ip: " + socket.getInetAddress());

            // 增加一個自動回覆
            OutputStream os = socket.getOutputStream();// 添加一個客戶端輸出
            PrintWriter pw = new PrintWriter(os);// 打印出來
            pw.print("welcome to my home!");// 打印的信息
            pw.flush();// 刷新打印

            InputStream is = socket.getInputStream();
            Scanner sc = new Scanner(is);
            String msg = "";
            while (sc.hasNextLine()) {
                msg = sc.nextLine();
                System.out.println(msg);
                if (msg.equals("exit")) {
                    System.out.println("再見!我要退出!");
                    System.exit(0);
                }
            }
            sc.close();
            is.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

這裏寫圖片描述


二、模擬一個廣播電臺(服務端向客服端發送信息)

    /**
     * 模擬一個廣播電臺,特點是隻能服務端說話,不能客戶端說話 
     * 步驟:
     * 1 創建一個服務端 
     * 2 接收一個客戶端
     * 3 創建一個服務端的輸入流(用於存儲系統輸入的數據流)
     * 4 創建一個客服的輸出流(用於在客服上顯示出數據)
     * 5 掃描打印,刷新打印
     */
     public static void broadcast(){
        try {
            ServerSocket server = new ServerSocket(8888);// 創建一個服務端,監聽端口8888
            Socket socket = server.accept();// 等待客戶端連接過來
            System.out.println("Ip: "+socket.getLocalAddress()+" 成功接入! ");

            OutputStream serverops1 = socket.getOutputStream();// 獲取來客的IP地址
            //自動回覆
            PrintWriter pw1 = new PrintWriter(serverops1);
            pw1.write("歡迎接入服務器!");
            pw1.flush();

            InputStream serverips = System.in;//在服務端輸入廣播內容做爲輸入流
            OutputStream serverops2 = socket.getOutputStream();//輸出流用於傳輸信息給客戶端
            PrintWriter pw = new PrintWriter(serverops2);
            //獲取信息
            Scanner sc = new Scanner(serverips);
            String msg="";
            while(sc.hasNextLine()){
                msg = sc.nextLine();
                pw.println(msg);//輸出信息
                pw.flush();
                if(msg.equals("exit")){
                    System.out.println("服務端講話完畢,再見!");
                    System.exit(0);
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

這裏寫圖片描述
這裏寫圖片描述


三、模擬一個對講機(半雙工模式)只能交替通話,不能同時通話

/**
     *  步驟:
     *  1 創建服務端 
     *  2 接收一個客戶端 
     *  3 創建一個服務端的輸入流(用於在服務端輸入)
     *  4 創建一個客戶端的輸出流(用於在客戶端顯示)
     *  5 創建一個客戶端的輸入流 (用於在服務端顯示)
     *  6 獲取客戶端發送的信息
     *  7 每次客戶端輸入一段話過來,我們都要從鍵盤輸入一段話,並且發送給客戶端
     */
        public static void connunication(){
        try {
            ServerSocket server = new ServerSocket(8888);// 創建一個服務端,監聽端口8888
            Socket socket = server.accept();//接收一個客戶端 

            Scanner scannerSystemIn = new Scanner(System.in);//創建一個服務端的輸入流(用於在服務端輸入)
            PrintWriter pw = new PrintWriter(socket.getOutputStream());//創建一個客戶端的輸出流(用於在客戶端顯示)
            Scanner scanner =new Scanner(socket.getInputStream());//創建一個客戶端的輸入流 (用於在服務端顯示)

            String msg = "";
            String serverMsg ="";
            while(scanner.hasNextLine()){//獲取客戶端發送的信息
                msg=scanner.nextLine();
                System.out.println("客戶端的輸入: "+msg);
                //當輸入exit 退出循環,結束通信
                if(msg.equals("exit")||serverMsg.equals("exit")){
                    System.out.println("退出連接!");
                    System.exit(0);
                }
                //每次客戶端輸入一段話過來,我們都要從鍵盤輸入一段話,並且發送給客戶端
                if(scannerSystemIn.hasNextLine()){
                    serverMsg = scannerSystemIn.nextLine();
                    System.out.println("服務端輸入: " + serverMsg);
                    pw.println("服務端說:"+serverMsg);
                    pw.flush();
                }
            }
            //關閉流
            pw.close();
            scannerSystemIn.close();
            scanner.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

這裏寫圖片描述
這裏寫圖片描述


四、做一個木馬文件

    /**
     * 客戶端可以通過輸入一個文件名傳給服務端,服務端就會根據文件的地址,將文件的內容返回給客戶端
     */
     public static void test5() {
        try {
            // 1:創建一個服務端,監聽一個端口
            ServerSocket serverSocket = new ServerSocket(8888);
            // 2:獲取一個客戶端對象
            Socket socket = serverSocket.accept();

            InputStream is = socket.getInputStream();
            Scanner scanner = new Scanner(is);
            PrintWriter pw = new PrintWriter(socket.getOutputStream());
            while (scanner.hasNextLine()) {
                // 3 接受客戶端的一個文件名
                String fileName = scanner.nextLine();
                // 4:讀取文件
                String content = getContentFromFile(fileName);
                // 5:把文件內容返回給客戶端
                pw.println(content);
                pw.flush();
            }
            is.close();
            socket.close();
            pw.close();

            // 4:
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

這裏寫圖片描述這裏寫圖片描述
這裏寫圖片描述


五、客戶端發送一個命令到服務端,服務端接收之後,在服務器執行這個命令,並把執行的結果返回給客戶端

    /**
     * 功能: 客戶端發送命令控制服務端,服務端返回執行結果給客戶端
     * 步驟:
     * 1、獲取客戶端發送給服務端的命令
     * 2、服務器運用進程的語句執行命令,保存執行的結果
     * 3、判斷執行結果
     * 4、將執行的結果發送給客戶端
     */
    public static void test() {
        try {
            ServerSocket server = new ServerSocket(8888);
            // 由於我們平時測試的時候,每次出錯或者每次在客戶端斷開連接的時候,服務端都會自動斷開
            // 爲了解決這個問題,我們寫了一個循環,當一個連接退出時,服務端自動進入下一個連接

            while (true) {
                Socket socket = server.accept();

                Scanner scanner = new Scanner(socket.getInputStream());
                PrintWriter pw = new PrintWriter(socket.getOutputStream());

                String command = "";
                String p1Content = "";
                String p2Content = "";
                // String p1go = "";
                while (scanner.hasNextLine()) {
                    command = scanner.nextLine();
                    Process p = Runtime.getRuntime().exec(command);
                    // 需要從進程執行後的結果中得到一個輸入流,這裏我們想要的信息
                    Scanner p1go = new Scanner(p.getInputStream());
                    while (p1go.hasNextLine()) {// 輸出到客戶端
                        p1Content = p1go.nextLine();
                        pw.println(p1Content);
                        pw.flush();
                    }
                    // 如果命令執行錯誤,就會有一個錯誤流
                    Scanner p2er = new Scanner(p.getErrorStream());
                    while (p2er.hasNextLine()) {
                        p2Content = p2er.nextLine();
                    }
                    // 如果錯誤流不爲空,就把錯誤信息輸出到客戶端
                    if (!p2Content.equals("")) {
                        pw.print(p2Content);
                        pw.flush();
                    }
                }
            }

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

    }

這裏寫圖片描述

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