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();
}
}
}
|
輸出結果:
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.
- 創建一個 ServerSocket 的 Object,綁定到指定的 Port
- 調用 accept() 方法,等待 client 連接
- 獲取到 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):傳送門
執行結果: