1.12-java socket程式設計 模擬2個機器人對話

如沐春風細雨中發表於2020-12-29

java socket網路程式設計 模擬2個機器人對話

上一篇:
下一篇:



前言

前面1.8 節,介紹了2個執行緒的通訊,模擬了2個機器人對話。
這節介紹2臺電腦之間的通訊,2臺電腦通訊需要用到網路。
socket(譯為套接字),是應用程式和網路通訊協議進行互動的介面,它向上為使用者(應用程式)提供操作網路的方法,向下實現與tcp/ip網路協議棧的對接。


提示:這節通過一個例子介紹使用java socket實現2臺主機網路通訊的基本方法。

一、編寫伺服器端程式

1、在IDEA中新建工程:socket-server,位置:E:\new\1.12\socket-server
2、新建包 com.my.socket
如下圖:
在這裡插入圖片描述
3、新建Server類,這是一個繼承了Thread的執行緒類。程式碼如下:

package com.my.socket;

import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Server extends Thread{
    //**伺服器啟動時佔用的埠號:預設5001*/
    private int port=5001;
    //server的名字
    private String name = "";
    //快取從socket讀的一行資料
    private String inLine ="";
    //快取寫入socket的一行資料
    private String outLine = "";
    //格式化日期顯示
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * Server 類的建構函式,
     * @param name server的名字
     * @param port server監聽的埠號
     */
   public Server(String name,int port){
        this.name = name;
        this.port = port;
        this.setName(name);
    }

    public void run(){
        try {
            System.out.println(name+":我準備好了。");
            // 建立一個伺服器端的Socket:ServerSocket
            ServerSocket serverSocket = new ServerSocket(port);
            // accept(),使程式阻塞監聽 埠 port,有連線申請時,就會得到一個Socket物件。
            Socket socket = serverSocket.accept();

            //從socket裡讀取資料的流
            BufferedReader socketIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //向socket裡寫資料的流
            PrintWriter socketOut = new PrintWriter(socket.getOutputStream());
            //控制對話結束標誌
            boolean chatting = true;
            while(chatting){
                //從socket讀一行
                inLine = socketIn.readLine();
                System.out.println(inLine);
                //如果客戶端說了拜拜,就不在繼續。
                if(inLine.contains("拜拜")){
                    outLine =name + ":拜拜";
                    chatting = false;
                }else{
                    //根據客戶端提出的問題找到答案
                    outLine =name + ":"+ answerQuestion(inLine.split(":")[1]);
                }
                //從socket中寫一行
                socketOut.println(outLine);
                System.out.println(outLine);
                //立即向客戶端傳送訊息
                socketOut.flush();
            }
            socketIn.close();
            socketOut.close();
            socket.close();
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    //根據問題得到答案
    private String answerQuestion(String question) {
        if(question == null){
            return "請開始提問...";
        }
        String an = "這個問題太難了,答不上來。";//預設回答語句
        if(question.equals("你叫什麼名字?")){
            an = this.getName();
        }else if(question.equals("現在幾點了?")){
            an = format.format(new Date());
        }else if(question.equals("你早飯吃的什麼?")){
            an = "豆漿和油條。";
        }else if(question.equals("你的身高多少?")){
            an = "身高1米9,腿長1米2。";
        }else if(question.equals("你最喜歡吃的美食是什麼?")){
            an = "麻辣水煮魚。";
        }else{

        }
        return an;
    }
}

4、新建啟動類:ServerApplication,main函式入口,程式碼如下:

package com.my.socket;

public class ServerApplication {
    public static void main(String[] args) {
        //建立伺服器執行緒
        Server server = new Server("大明",5001);
        //啟動執行緒
        server.start();
    }
}

二、編寫客戶端程式

1、在IDEA中新建工程:socket-client
位置:E:\new\1.12\socket-client
2、新建包:com.my.socket
在這裡插入圖片描述
3、建立Client類,這是繼承製Thread的執行緒類,程式碼如下:

package com.my.socket;

import java.io.*;
import java.net.*;

public class Client extends Thread{
    /**訪問伺服器的埠,與伺服器的監聽埠一致*/
    private int port=5001;
    /**客戶端的名稱*/
    private String name = "";

    //佔存 從socket讀的一行資料
    private String inLine ="";
    //佔存 寫入socket的一行資料
    private String outLine = "";

    /**
     * 客戶端 Client的建構函式
     * @param name 名字
     * @param port 埠
     */
    public Client(String name,int port){
        this.name = name;
        this.port = port;
    }

    public void run(){
        System.out.println(name+":我開始問了。");
        //連線伺服器的ip地址,這裡連線的是本機,因此是127.0.0.1
        byte ipAddressTemp[] = {127,0,0,1};
        InetAddress ipAddress = null;
        try {
            ipAddress = InetAddress.getByAddress(ipAddressTemp);
            //建立socket連線,連線成功就能得到一個socket物件,可進行通訊;連線失敗則丟擲異常
            Socket socket = new Socket(ipAddress, port);
            //獲取socket的輸入流,用於從socket中讀資料
            BufferedReader socketIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //獲取socket的輸出流,用於向socket中寫資料
            PrintWriter socketOut = new PrintWriter(socket.getOutputStream());
            //結束對話標誌
            boolean chatting = true;
            while(chatting){
                //客戶端提問,隨機獲取一個問題
                outLine = name + ":"+ Language.getARandomQuestion();
                socketOut.println(outLine);
                System.out.println(outLine);
                socketOut.flush();
                //收到服務端的回答
                inLine = socketIn.readLine();
                System.out.println(inLine);
                //伺服器說拜拜就不說了
                if(inLine.contains("拜拜")){
                    outLine =name + ":"+ "拜拜";
                    chatting = false;
                }else{

                }
                socketOut.flush();
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            socketIn.close();
            socketOut.close();
            socket.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4、建立Language物件,用來儲存對話問題。程式碼如下:

package com.my.socket;

import java.util.Random;

//預先設定好可能的對話內容
public class Language {
    //問題集合
    static final String[] questions = {
            "你叫什麼名字?",
            "現在幾點了?",
            "你早飯吃的什麼?",
            "你中午吃的什麼?",
            "你晚餐吃的什麼?",
            "你的身高多少?",
            "你最喜歡吃的美食是什麼?",
            "拜拜"
    };
    //隨機數生成器
    static Random random = new Random();
    //當前問題
    static String question = null;
    //當前答案
    static String answer = null;

    /**隨機獲取一個問題*/
    public static String getARandomQuestion() {
        int index = random.nextInt(questions.length);
        return questions[index];
    }
    //設定當前答案
    public static void setAnswer(String answer) {
        Language.answer = answer;
    }
    //設定當前問題
    public static void setQuestion(String question) {
        Language.question = question;
    }
}

5、建立ClientApplication用於啟動客戶端執行緒:

package com.my.socket;

public class ClientApplication {
    public static void main(String[] args) {
        Client client = new Client("小明",5001);
        client.start();
    }
}

三、執行

1、先啟動伺服器端,啟動好在啟動客戶端程式。執行結果如下:
每次執行的結果可能不同,當客戶端傳送含“拜拜”字元的,就會結束對話。
在這裡插入圖片描述

相關文章