目錄

興大物件導向程式設計 Assignment Ch28 參考詳解

28.3

Distinguish between connection-oriented and connectionless network services.

  • Connection-oriented network services
    • 在傳輸數據前必須先建立連接(eg. TCP
    • 數據傳輸穩定可靠,可以確保傳輸的數據按順序到達、完整傳達
  • Connectionless network services
    • 直接發送數據,不需要先建立連接(eg. UDP
    • 數據可能會丟失、重覆、亂序送達

28.4

How does a client determine the host name of the client computer?

可以從電腦的設定中查看,也可以用 Java 程式取得:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import java.net.InetAddress;
import java.net.UnknownHostException;

public class Test {
    public static void main(String[] args) {
        try {
            InetAddress addr = InetAddress.getLocalHost();
            String hostname = addr.getHostName();
            System.out.println("Host name: " + hostname);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

輸出結果:

/nchu-java-oop-assignment-ch28-solution/getHostName.webp

28.5

Under what circurmstances would a Socket Exception be thrown?

  • 試著連接到一個已關閉的 port(連接埠/端口)
  • 在傳輸數據的過程中,連接意外中斷
  • 網路錯誤導致傳輸失敗
  • 客戶端(Client)或伺服器(Server)的資源耗盡

28.6

How can a client get a line of text from a server?

客戶端透過 Socket 連接到 Server 後,可以使用 BufferedReader 從 InputStream 中讀取文字。 假設 Server 的 ip 是 localhost:8080

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;

public class Client {
    public static void main(String[] args) {
        try (Socket socket = new Socket("localhost", 8080);
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

28.7

Describe how a client connects to a server.

一樣假設 Server 的 ip 是 localhost:8080

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import java.net.Socket;

public class Client {
    public static void main(String[] args) {
        try (Socket socket = new Socket("localhost", 8080)) {
            System.out.println("Connected to the server");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

28.8

Describe how a server sends data to a client.

伺服器可以使用 OutputStream 向已連接的 Client 發送數據:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(8000)) {
            System.out.println("Server is listening on port 8000");
            Socket socket = serverSocket.accept();
            OutputStream out = socket.getOutputStream();
            out.write("Hello, Client".getBytes());
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

28.9

Describe how to prepare a server to receive a stream-based connection from a single client.

  1. 創建一個 ServerSocket 的 Object,綁定到指定的 Port
  2. 調用 accept() 方法,等待 client 連接
  3. 獲取到 Socket Object 後,通過 InputStream 和 OutputStream 進行數據傳輸
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class SingleClientServer {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(8080)) {
            System.out.println("Server is listening on port 8080");
            Socket socket = serverSocket.accept();
            System.out.println("Client connected");

            // 使用 BufferedReader 和 PrintWriter 傳輸數據
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            String clientMessage;
            while ((clientMessage = in.readLine()) != null) {
                System.out.println("Client says: " + clientMessage);
            }

            socket.close();
            System.out.println("Client disconnected");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

28.10

How does a server listen for stream-based socket connections at a port?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package anytime;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(8000)) {
            System.out.println("Server is listening on port 8000");
            while (true) {
                Socket socket = serverSocket.accept();
                System.out.println("New client connected: " + socket.getInetAddress());

                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

                String clientMessage;
                while ((clientMessage = in.readLine()) != null) {
                    System.out.println("Client says: " + clientMessage);
                    out.println("Server received: " + clientMessage);
                }

                socket.close();
                System.out.println("Client disconnected: " + socket.getInetAddress());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

28.13

Write an JAVA application and use a socket connection to allow a cliet to specify a filename of a text file (test.txt) and have the server send the concents of the file or indicate that the file does not exist.

程式碼(Github):傳送門

執行結果:

/nchu-java-oop-assignment-ch28-solution/finalResult.webp