
Java 教程
- Java - 首頁
- Java - 概述
- Java - 歷史
- Java - 特性
- Java vs. C++
- JVM - Java虛擬機器
- Java - JDK vs JRE vs JVM
- Java - Hello World 程式
- Java - 環境搭建
- Java - 基本語法
- Java - 變數型別
- Java - 資料型別
- Java - 型別轉換
- Java - Unicode 系統
- Java - 基本運算子
- Java - 註釋
- Java - 使用者輸入
- Java - 日期和時間
Java 控制語句
- Java - 迴圈控制
- Java - 決策制定
- Java - if-else
- Java - switch
- Java - for 迴圈
- Java - for-each 迴圈
- Java - while 迴圈
- Java - do-while 迴圈
- Java - break
- Java - continue
面向物件程式設計
- Java - 面向物件程式設計概念
- Java - 物件和類
- Java - 類屬性
- Java - 類方法
- Java - 方法
- Java - 變數作用域
- Java - 建構函式
- Java - 訪問修飾符
- Java - 繼承
- Java - 聚合
- Java - 多型
- Java - 方法重寫
- Java - 方法過載
- Java - 動態繫結
- Java - 靜態繫結
- Java - 例項初始化塊
- Java - 抽象
- Java - 封裝
- Java - 介面
- Java - 包
- Java - 內部類
- Java - 靜態類
- Java - 匿名類
- Java - 單例類
- Java - 包裝類
- Java - 列舉
- Java - 列舉建構函式
- Java - 列舉字串
Java 內建類
Java 檔案處理
Java 錯誤和異常
- Java - 異常
- Java - try-catch 塊
- Java - try-with-resources
- Java - 多重catch塊
- Java - 巢狀try塊
- Java - finally 塊
- Java - throw 異常
- Java - 異常傳播
- Java - 內建異常
- Java - 自定義異常
Java 多執行緒
- Java - 多執行緒
- Java - 執行緒生命週期
- Java - 建立執行緒
- Java - 啟動執行緒
- Java - 執行緒連線
- Java - 執行緒命名
- Java - 執行緒排程器
- Java - 執行緒池
- Java - 主執行緒
- Java - 執行緒優先順序
- Java - 守護執行緒
- Java - 執行緒組
- Java - 關閉鉤子
Java 同步
Java 網路程式設計
- Java - 網路程式設計
- Java - Socket 程式設計
- Java - URL 處理
- Java - URL 類
- Java - URLConnection 類
- Java - HttpURLConnection 類
- Java - Socket 類
- Java -泛型
Java 集合
Java 介面
Java 資料結構
Java 集合演算法
高階 Java
- Java - 命令列引數
- Java - Lambda 表示式
- Java - 傳送郵件
- Java - Applet 基礎
- Java - Javadoc 註釋
- Java - 自動裝箱和拆箱
- Java - 檔案不匹配方法
- Java - REPL (JShell)
- Java - 多版本 Jar 檔案
- Java - 私有介面方法
- Java - 內部類菱形運算子
- Java - 多解析度影像API
- Java - 集合工廠方法
- Java - 模組系統
- Java - Nashorn JavaScript
- Java - Optional 類
- Java - 方法引用
- Java - 函式式介面
- Java - 預設方法
- Java - Base64 編碼解碼
- Java - switch 表示式
- Java - Teeing Collectors
- Java - 微基準測試
- Java - 文字塊
- Java - 動態 CDS 歸檔
- Java - Z 垃圾收集器 (ZGC)
- Java - 空指標異常
- Java - 打包工具
- Java - 密封類
- Java - 記錄類
- Java - 隱藏類
- Java - 模式匹配
- Java - 簡潔數字格式化
- Java - 垃圾收集
- Java - JIT 編譯器
Java 其他
- Java - 遞迴
- Java - 正則表示式
- Java - 序列化
- Java - 字串
- Java - Process API 增強
- Java - Stream API 增強
- Java - 增強@Deprecated 註解
- Java - CompletableFuture API 增強
- Java - 流
- Java - 日期時間 API
- Java 8 - 新特性
- Java 9 - 新特性
- Java 10 - 新特性
- Java 11 - 新特性
- Java 12 - 新特性
- Java 13 - 新特性
- Java 14 - 新特性
- Java 15 - 新特性
- Java 16 - 新特性
Java APIs 和框架
Java 類引用
- Java - Scanner
- Java - 陣列
- Java - 字串
- Java - Date
- Java - ArrayList
- Java - Vector
- Java - Stack
- Java - PriorityQueue
- Java - LinkedList
- Java - ArrayDeque
- Java - HashMap
- Java - LinkedHashMap
- Java - WeakHashMap
- Java - EnumMap
- Java - TreeMap
- Java - IdentityHashMap
- Java - HashSet
- Java - EnumSet
- Java - LinkedHashSet
- Java - TreeSet
- Java - BitSet
- Java - Dictionary
- Java - Hashtable
- Java - Properties
- Java - Collection
- Java - Array
Java 有用資源
Java - 網路程式設計
Java 網路程式設計
Java 網路程式設計 指的是編寫在多個裝置(計算機)上執行的程式,這些裝置透過網路相互連線。
Java 網路程式設計的優勢
- 建立伺服器-客戶端應用程式
- 實現網路協議
- 實現套接字程式設計
- 建立 Web 服務
網路程式設計中使用的包
J2SE API 的 java.net 包包含一系列類和介面,它們提供了底層的通訊細節,允許您編寫專注於解決問題的程式。
java.net 包為兩種常見的網路協議提供支援:
TCP − TCP 代表傳輸控制協議,它允許兩個應用程式之間進行可靠的通訊。TCP 通常用於網際網路協議之上,稱為 TCP/IP。
UDP − UDP 代表使用者資料報協議,這是一種無連線的協議,允許在應用程式之間傳輸資料包。
本章對以下兩個主題進行了很好的講解:
套接字程式設計 − 這是網路程式設計中最常用的概念,已進行詳細解釋。
URL 處理 − 這將在單獨章節中介紹。點選此處瞭解 Java 語言中的URL 處理。
Java 網路程式設計中的套接字程式設計
套接字使用 TCP 提供兩臺計算機之間的通訊機制。客戶端程式在其通訊端建立一個套接字,並嘗試將該套接字連線到伺服器。
建立連線後,伺服器在其通訊端建立一個套接字物件。客戶端和伺服器現在可以透過寫入和讀取套接字進行通訊。
java.net.Socket 類表示套接字,java.net.ServerSocket 類為伺服器程式提供了一種機制,用於監聽客戶端並與之建立連線。
使用套接字在兩臺計算機之間建立 TCP 連線時,會發生以下步驟:
伺服器例項化一個 ServerSocket 物件,表示要進行通訊的埠號。
伺服器呼叫 ServerSocket 類的 accept() 方法。此方法一直等到客戶端連線到給定埠上的伺服器。
伺服器等待後,客戶端例項化一個 Socket 物件,指定要連線到的伺服器名稱和埠號。
Socket 類的建構函式嘗試將客戶端連線到指定的伺服器和埠號。如果建立了通訊,則客戶端現在擁有一個能夠與伺服器通訊的 Socket 物件。
在伺服器端,accept() 方法返回對伺服器上連線到客戶端套接字的新套接字的引用。
建立連線後,可以使用 I/O 流進行通訊。每個套接字都有一個 OutputStream 和一個 InputStream。客戶端的 OutputStream 連線到伺服器的 InputStream,客戶端的 InputStream 連線到伺服器的 OutputStream。
TCP 是一種雙向通訊協議,因此資料可以同時透過兩個流傳送。以下是提供完整方法集以實現套接字的有用類。
ServerSocket 類建構函式
java.net.ServerSocket 類用於伺服器應用程式獲取埠並監聽客戶端請求。
ServerSocket 類有四個建構函式:
序號 | 方法和描述 |
---|---|
1 | public ServerSocket(int port) throws IOException 嘗試建立一個繫結到指定埠的伺服器套接字。如果埠已被其他應用程式繫結,則會發生異常。 |
2 | public ServerSocket(int port, int backlog) throws IOException 與之前的建構函式類似,backlog 引數指定在等待佇列中儲存多少個傳入客戶端。 |
3 | public ServerSocket(int port, int backlog, InetAddress address) throws IOException 與之前的建構函式類似,InetAddress 引數指定要繫結的本地 IP 地址。對於可能具有多個 IP 地址的伺服器,InetAddress 用於允許伺服器指定其哪個 IP 地址用於接受客戶端請求。 |
4 | public ServerSocket() throws IOException 建立一個未繫結的伺服器套接字。使用此建構函式時,準備好繫結伺服器套接字後,請使用 bind() 方法。 |
如果 ServerSocket 建構函式沒有丟擲異常,則表示您的應用程式已成功繫結到指定的埠,並已準備好接受客戶端請求。
ServerSocket 類方法
以下是 ServerSocket 類的一些常用方法:
序號 | 方法和描述 |
---|---|
1 | public int getLocalPort() 返回伺服器套接字正在監聽的埠。如果您在建構函式中傳入 0 作為埠號並讓伺服器為您查詢埠,則此方法很有用。 |
2 | public Socket accept() throws IOException 等待傳入客戶端。此方法會阻塞,直到客戶端連線到指定埠上的伺服器或套接字超時(假設已使用 setSoTimeout() 方法設定了超時值)。否則,此方法將無限期阻塞。 |
3 | public void setSoTimeout(int timeout) 設定伺服器套接字在 accept() 期間等待客戶端的時間超時值。 |
4 | public void bind(SocketAddress host, int backlog) 將套接字繫結到 SocketAddress 物件中指定的伺服器和埠。如果您使用無引數建構函式例項化了 ServerSocket,請使用此方法。 |
當 ServerSocket 呼叫 accept() 時,該方法在客戶端連線之前不會返回。客戶端連線後,ServerSocket 會在未指定的埠上建立一個新的 Socket,並返回對這個新 Socket 的引用。現在客戶端和伺服器之間存在 TCP 連線,可以開始通訊。
Socket 類建構函式
java.net.Socket 類表示客戶端和伺服器都用來彼此通訊的套接字。客戶端透過例項化一個 Socket 物件來獲取它,而伺服器則從 accept() 方法的返回值獲取 Socket 物件。
Socket 類有五個建構函式,客戶端可以使用它們來連線到伺服器:
序號 | 方法和描述 |
---|---|
1 | public Socket(String host, int port) throws UnknownHostException, IOException. 此方法嘗試連線到指定埠上的指定伺服器。如果此建構函式沒有丟擲異常,則連線成功,客戶端已連線到伺服器。 |
2 | public Socket(InetAddress host, int port) throws IOException 此方法與之前的建構函式相同,只是主機由 InetAddress 物件表示。 |
3 | public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException. 連線到指定的主機和埠,在本地主機上建立套接字,地址和埠由引數指定。 |
4 | public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException. 此方法與之前的建構函式相同,只是主機由 InetAddress 物件而不是 String 表示。 |
5 | public Socket() 建立一個未連線的套接字。使用 connect() 方法將此套接字連線到伺服器。 |
當 Socket 建構函式返回時,它不僅會例項化一個 Socket 物件,還會嘗試連線到指定的伺服器和埠。
Socket 類方法
這裡列出了一些 Socket 類中值得關注的方法。請注意,客戶端和伺服器都有一個 Socket 物件,因此這些方法可以由客戶端和伺服器呼叫。
序號 | 方法和描述 |
---|---|
1 | public void connect(SocketAddress host, int timeout) throws IOException 此方法將套接字連線到指定的主機。僅當您使用無引數建構函式例項化 Socket 時才需要此方法。 |
2 | public InetAddress getInetAddress() 此方法返回此套接字連線到的另一臺計算機的地址。 |
3 | public int getPort() 返回套接字在遠端計算機上繫結的埠。 |
4 | public int getLocalPort() 返回套接字在本地計算機上繫結的埠。 |
5 | public SocketAddress getRemoteSocketAddress() 返回遠端套接字的地址。 |
6 | public InputStream getInputStream() throws IOException 返回套接字的輸入流。輸入流連線到遠端套接字的輸出流。 |
7 | public OutputStream getOutputStream() throws IOException 返回套接字的輸出流。輸出流連線到遠端套接字的輸入流。 |
8 | public void close() throws IOException 關閉套接字,這使得此 Socket 物件不再能夠連線到任何伺服器。 |
InetAddress 類方法
此類表示網際網路協議 (IP) 地址。以下是在進行套接字程式設計時可能需要的一些有用方法:
序號 | 方法和描述 |
---|---|
1 | static InetAddress getByAddress(byte[] addr) 給定原始 IP 地址,返回一個 InetAddress 物件。 |
2 | static InetAddress getByAddress(String host, byte[] addr) 基於提供的主機名和 IP 地址建立 InetAddress。 |
3 | static InetAddress getByName(String host) 根據主機名確定主機的 IP 地址。 |
4 | String getHostAddress() 以文字形式返回 IP 地址字串。 |
5 | String getHostName() 獲取此 IP 地址的主機名。 |
6 | static InetAddress InetAddress getLocalHost() 返回本地主機。 |
7 | String toString() 將此 IP 地址轉換為字串。 |
Java 網路程式設計示例
在 Java 中實現 Socket 客戶端
下面的 GreetingClient 是一個客戶端程式,它使用套接字連線到伺服器,傳送問候語,然後等待響應。
示例:Socket 客戶端
// File Name GreetingClient.java import java.net.*; import java.io.*; public class GreetingClient { public static void main(String [] args) { String serverName = args[0]; int port = Integer.parseInt(args[1]); try { System.out.println("Connecting to " + serverName + " on port " + port); Socket client = new Socket(serverName, port); System.out.println("Just connected to " + client.getRemoteSocketAddress()); OutputStream outToServer = client.getOutputStream(); DataOutputStream out = new DataOutputStream(outToServer); out.writeUTF("Hello from " + client.getLocalSocketAddress()); InputStream inFromServer = client.getInputStream(); DataInputStream in = new DataInputStream(inFromServer); System.out.println("Server says " + in.readUTF()); client.close(); } catch (IOException e) { e.printStackTrace(); } } }
在 Java 中實現 Socket 伺服器
下面的 GreetingServer 程式是一個伺服器應用程式示例,它使用 Socket 類監聽命令列引數指定的埠號上的客戶端:
示例:Socket 伺服器
// File Name GreetingServer.java import java.net.*; import java.io.*; public class GreetingServer extends Thread { private ServerSocket serverSocket; public GreetingServer(int port) throws IOException { serverSocket = new ServerSocket(port); serverSocket.setSoTimeout(10000); } public void run() { while(true) { try { System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "..."); Socket server = serverSocket.accept(); System.out.println("Just connected to " + server.getRemoteSocketAddress()); DataInputStream in = new DataInputStream(server.getInputStream()); System.out.println(in.readUTF()); DataOutputStream out = new DataOutputStream(server.getOutputStream()); out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress() + "\nGoodbye!"); server.close(); } catch (SocketTimeoutException s) { System.out.println("Socket timed out!"); break; } catch (IOException e) { e.printStackTrace(); break; } } } public static void main(String [] args) { int port = Integer.parseInt(args[0]); try { Thread t = new GreetingServer(port); t.start(); } catch (IOException e) { e.printStackTrace(); } } }
編譯客戶端和伺服器,然後按如下方式啟動伺服器:
$ java GreetingServer 6066 Waiting for client on port 6066...
按如下方式檢查客戶端程式:
輸出
$ java GreetingClient localhost 6066 Connecting to localhost on port 6066 Just connected to localhost/127.0.0.1:6066 Server says Thank you for connecting to /127.0.0.1:6066 Goodbye!