Java 網絡程式設計 UDP TCP
0x00 概述
本文主要涉及Java知識點為Java網絡程式設計。
0x01 網絡程式設計入門
1.1 網絡程式設計概述
- 計算機網絡
是指将地理位置不同的具有獨立功能的多台計算機及其外部裝置,通過通信線路連接配接起來,
在網絡作業系統,網絡管理軟體及網絡通信協定的管理和協調下,實作資源共享和資訊傳遞的計算機系統
- 網絡程式設計
在網絡通信協定下,實作網絡互連的不同計算機上運作的程式間可以進行資料交換
1.2 網絡程式設計三要素
- IP位址
想讓網絡中的計算機能夠互相通信,必須為每台計算機指定一個辨別号,
通過這個辨別号來指定要接收數 據的計算機和識别發送的計算機,而IP位址就是這個辨別号,也就是裝置的辨別
- 端口
網絡的通信,本質上是兩個應用程式的通信。每台計算機都有很多的應用程式,那麼在網絡通信時,如何區分這些應用程式呢?
如果說IP位址可以唯一辨別網絡中的裝置,那麼端口号就可以唯一辨別裝置中的應用程式 了,也就是應用程式的辨別
- 協定
通過計算機網絡可以使多台計算機實作連接配接,位于同一個網絡中的計算機在進行連接配接和通信時需要遵守一定 的規則,這就好比在道路中行駛的汽車一定要遵守交通規則一樣。
在計算機網絡中,這些連接配接和通信的規則 被稱為網絡通信協定,它對資料的傳輸格式、傳輸速率、傳輸步驟等做了統一規定,通信雙方必須同時遵守 才能完成資料交換。
常見的協定有UDP協定和TCP協定
1.3 IP位址
- IP位址:是網絡裝置中的唯一辨別
- IP位址分為兩大類
IPv4:是給每個連接配接在網絡上的主機配置設定一個32bit位址。按照TCP/IP規定,IP位址用二進制來表示,每
個IP位址長32bit,也就是4個位元組。例如一個采用二進制形式的IP位址是“11000000 10101000
00000001 01000010”,這麼長的位址,處理起來也太費勁了。為了友善使用,IP位址經常被寫成十進制
的形式,中間使用符号“.”分隔不同的位元組。于是,上面的IP位址可以表示為“192.168.1.66”。IP位址的這
種表示法叫做“點分十進制表示法”,這顯然比1和0容易記憶得多
IPv6:由于網際網路的蓬勃發展,IP位址的需求量愈來愈大,但是網絡位址資源有限,使得IP的配置設定越發
緊張。為了擴大位址空間,通過IPv6重新定義位址空間,采用128位位址長度,每16個位元組一組,分成8
組十六進制數,這樣就解決了網絡位址資源數量不夠的問題
- DOS常用指令
ipconfig:檢視本機IP位址
ping IP位址:檢查網絡是否連通
- 特殊IP位址
127.0.0.1:是回送位址,可以代表本機位址,一般用來測試使用
1.4 InetAddress
- netAddress:此類表示Internet協定(IP)位址
- 相關方法

示例
package InetAddressDemo;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class InetAddressDemo {
public static void main(String[] args) throws UnknownHostException {
// InetAddress address = InetAddress.getByName("Test");
InetAddress address = InetAddress.getByName("127.0.0.1");
// public String getHostName(): 擷取此IP位址的主機名
String name = address.getHostName();
// public String getHostAddress(): 傳回文本顯示中的IP位址字元串
String ip = address.getHostAddress();
System.out.println("主機名: " + name);
System.out.println("IP位址:" + ip);
}
}
1.5 端口和協定
- 端口
裝置上應用程式的唯一辨別
- 端口号
用兩個位元組表示的整數,它的取值範圍是0~65535。其中,0~1023之間的端口号用于一些知名的網絡服 務和應用,普通的應用程式需要使用1024以上的端口号。
如果端口号被另外一個服務或應用所占用,會 導緻目前程式啟動失敗
- 協定
計算機網絡中,連接配接和通信的規則被稱為網絡通信協定
- UDP協定
使用者資料報協定(User Datagram Protocol)
UDP是無連接配接通信協定,即在資料傳輸時,資料的發送端和接收端不建立邏輯連接配接。
簡單來說,當一台 計算機向另外一台計算機發送資料時,發送端不會确認接收端是否存在,就會發出資料,同樣接收端在 收到資料時,也不會向發送端回報是否收到資料。
由于使用UDP協定消耗資源小,通信效率高,是以通常都會用于音頻、視訊和普通資料的傳輸
例如視訊會議通常采用UDP協定,因為這種情況即使偶爾丢失一兩個資料包,也不會對接收結果産生太大影響
但是在使用UDP協定傳送資料時,由于UDP的面向無連接配接性,不能保證資料的完整性,是以在傳輸重要資料時不建議使用UDP協定
- TCP協定
傳輸控制協定 (Transmission Control Protocol)
TCP協定是面向連接配接的通信協定,即傳輸資料之前,在發送端和接收端建立邏輯連接配接,然後再傳輸資料,它提供了兩台計算機之間可靠無差錯的資料傳輸。
在TCP連接配接中必須要明确用戶端與伺服器端,由用戶端向服務端發出連接配接請求,每次連接配接的建立都需要經過“三次握手”
三次握手:TCP協定中,在發送資料的準備階段,用戶端與伺服器之間的三次互動,以保證連接配接的可靠
第一次握手,用戶端向伺服器端發出連接配接請求,等待伺服器确認
第二次握手,伺服器端向用戶端回送一個響應,通知用戶端收到了連接配接請求
第三次握手,用戶端再次向伺服器端發送确認資訊,确認連接配接
完成三次握手,連接配接建立後,用戶端和伺服器就可以開始進行資料傳輸了。
由于這種面向連接配接的特性, TCP協定可以保證傳輸資料的安全,是以應用十分廣泛。例如上傳檔案、下載下傳檔案、浏覽網頁等
0x02 UDP通信程式
2.1 UDP發送資料
- Java中的UDP通信
UDP協定是一種不可靠的網絡協定,它在通信的兩端各建立一個Socket對象,但是這兩個Socket隻是發送,接收資料的對象,
是以對于基于UDP協定的通信雙方而言,沒有所謂的用戶端和伺服器的概念
Java提供了DatagramSocket類作為基于UDP協定的Socket
- 構造方法
- 相關方法
- 發送資料的步驟
建發送端的Socket對象(DatagramSocket)
建立資料,并把資料打包
調用DatagramSocket對象的方法發送資料
關閉發送端
示例
package SendDemo;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class SendDemo {
public static void main(String[] args) throws IOException {
// 建立發送端的Socket對象(DatagramSocket)
// DatagramSocket ds = new DatagramSocket();
DatagramSocket ds = new DatagramSocket();
// 建立資料,并把資料打包
// DatagramPacket(byte[] buf, int length, InetAddress address, int port)
// 構造一個資料包,發送長度為length的資料包到指定主機上的指定端口
byte[] bys = "Hello, This is a test".getBytes();
DatagramPacket dp =
new DatagramPacket(bys, bys.length, InetAddress.getByName("127.0.0.1"), 100010);
// 調用DataGramSocket對象的方法發送資料
// void send(DatagramPacket p) 從此套接字發送資料包
ds.send(dp);
// 關閉發送端
// void close() 關閉此資料報套接字
ds.close();
}
}
2.2 UDP接受資料
- 接收資料的步驟
建立接收端的Socket對象(DatagramSocket)
建立一個資料包,用于接收資料
調用DatagramSocket對象的方法接收資料
解析資料包,并把資料在控制台顯示
關閉接收端
- 構造方法
- 相關方法
示例
package ReceiveDemo;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
// 建立接收端的Socket對象(DatagramSocket)
DatagramSocket ds = new DatagramSocket(10010);
while (true) {
// 建立一個資料包,用于接收資料
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length);
// 調用DatagramSocket對象的方法接收資料
ds.receive(dp);
// 解析資料包,并把資料在控制台顯示
System.out.println("資料是: " + new String(dp.getData(), 0, dp.getLength()));
}
}
}
2.3 UDP通信程式聯系
- 需求:
UDP發送資料:資料來自于鍵盤錄入,直到輸入的資料是886,發送資料結束
UDP接收資料:因為接收端不知道發送端什麼時候停止發送,故采用死循環接收
示例
package SendReceiveDemo;
/*
UDP發送資料:
資料來自于鍵盤錄入,直到輸入的資料是886,發送資料結束
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class SendDemo {
public static void main(String[] args) throws IOException {
// 建立發送端的Socket對象(DatagramSocket)
DatagramSocket ds = new DatagramSocket();
// 自己封裝鍵盤錄入資料
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = br.readLine()) != null) {
// 資料資料是886,發送資料結束
if ("886".equals(line)) {
break;
}
// 建立資料,并把資料打包
byte[] bys = line.getBytes();
DatagramPacket dp = new DatagramPacket(bys, bys.length,
InetAddress.getByName("127.0.0.1"), 12345);
// 調用DatagramSocket對象的方法發送資料
ds.send(dp);
}
// 關閉發送端
ds.close();
}
}
package SendReceiveDemo;
/*
UDP接收資料
因為接收端不知道發送端什麼時候停止發送資料,是以采用死循環方式接收
*/
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
// 建立接收端的Socket對象(DatagramSocket)
DatagramSocket ds = new DatagramSocket(12345);
while (true) {
// 建立一個資料包,用于接收資料
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length);
// 調用DatagramSocket對象接收資料
ds.receive(dp);
// 解析資料包,并把資料在控制台顯示
System.out.println("資料是: " + new String(dp.getData(), 0, dp.getLength()));
}
// 關閉接收端
// ds.close();
}
}
0x03 TCP通信程式
3.1 TCP發送資料
- Java中的TCP通信
Java對基于TCP協定的的網絡提供了良好的封裝,使用Socket對象來代表兩端的通信端口,并通過Socket産生IO流來進行網絡通信
Java為用戶端提供了Socket類,為伺服器端提供了ServerSocket類
- 構造方法
- 相關方法
示例
package clientDemo;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class clientDemo {
public static void main(String[] args) throws IOException {
// 建立用戶端的Socket對象(Socket)
// Socket(String host, int port) 建立流套接字并将其連接配接到指定主機上的端口
Socket s = new Socket("127.0.0.1", 12345);
// 擷取輸出流,寫資料
// OutputStream getOutPutStream() 傳回此套接字的輸出流
OutputStream os = s.getOutputStream();
os.write("Hello, this a test".getBytes());
// 釋放資源
s.close();
}
}
3.2 TCP接受資料
- 構造方法
- 相關方法
示例
package ServerDemo;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 建立伺服器端的Socket對象(ServerSocket)
// ServerSocket(int port) 建立綁定到指定端口的伺服器套接字
ServerSocket ss = new ServerSocket(12345);
// Socket accept() 偵聽要連接配接到此套接字并接受它
Socket s = ss.accept();
// 擷取輸入流,寫資料,并把資料顯示在控制台
// OutputStream getOutputStream() 傳回此套接字的輸出流
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String data = new String(bys, 0, len);
// 釋放資源
s.close();
ss.close();
}
}
3.3 TCP通信練習1
- 需求:
用戶端:發送資料,接受伺服器回報
伺服器:收到消息後給出回報
- 案例分析
用戶端建立對象,使用輸出流輸出資料
服務端建立對象,使用輸入流接受資料
服務端使用輸出流給出回報資料
用戶端使用輸入流接受回報資料
示例
package ServerClientTCPDemo1;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 建立伺服器端的Socket對象(ServerSocket)
ServerSocket ss = new ServerSocket(12345);
// 監聽用戶端連接配接,傳回一個Socket對象
Socket s = ss.accept();
// 擷取輸入流,讀取資料,并把資料顯示在控制台
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String data = new String(bys, 0, len);
System.out.println("伺服器: " + data);
// 給出回報
OutputStream os = s.getOutputStream();
os.write("資料已收到:".getBytes());
// 釋放資源
// s.close();
ss.close();
}
}
package ServerClientTCPDemo1;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 建立用戶端的Socket對象
Socket s = new Socket("127.0.0.1", 12345);
// 擷取輸出流,寫資料
OutputStream os = s.getOutputStream();
os.write("Hello, this is a test message".getBytes());
// 接收伺服器回報
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String data = new String(bys, 0, len);
System.out.println("用戶端: " + data);
// 釋放資源
// is.close();
// os.close();
s.close();
}
}
3.4 TCP通信練習2
- 需求:
用戶端:資料來自于鍵盤錄入, 直到輸入的資料是886,發送資料結束
服務端:接收到資料在控制台輸出
- 案例分析
用戶端建立對象,使用鍵盤錄入循環接受資料,接受一行發送一行,直到鍵盤錄入886為止
服務端建立對象,使用輸入流按行循環接受資料,直到接受到null為止
示例
package ServerClientTCPDemo2;
import java.io.*;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 建立socket對象
Socket s = new Socket("127.0.0.1", 12345);
// 資料來自鍵盤錄入,直到輸入的資料是886,發送資料結束
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 封裝輸出流對象
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
while ((line = br.readLine()) != null) {
if ("886".equals(line)) {
break;
}
// 擷取輸出流對象
bw.write(line);
bw.newLine();
bw.flush();
}
// 釋放資源
s.close();
}
}
package ServerClientTCPDemo2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 建立伺服器Socket對象
ServerSocket ss = new ServerSocket();
// 監聽用戶端的連接配接,傳回一個對應的Socket對象
Socket s = ss.accept();
// 擷取輸入流
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
// 釋放資源
ss.close();
}
}
3.5 TCP通信練習3
- 需求:
用戶端:資料來自于鍵盤錄入,直到輸入的資料是886,發送資料結束
服務端:接受到的資料寫入文本檔案中
- 案例分析:
用戶端建立對象,使用鍵盤錄入循環接受資料,接受一行發送一行,直到鍵盤錄入886為止
服務端建立對象,建立輸出流對象指向檔案,每接受一行資料後使用輸出流輸出到檔案中,直到接收到null為止
示例
package ServerClientTCPDemo3;
import java.io.*;
import java.net.Socket;
public class clientDemo {
public static void main(String[] args) throws IOException {
// 建立用戶端Socket對象
Socket s = new Socket("127.0.0.1", 12345);
// 資料來自鍵盤錄入,直到輸入的資料是886,發送資料結束
BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
// 封裝輸出流對象
BufferedWriter bw = new BufferedWriter(new
OutputStreamWriter(s.getOutputStream()));
String line;
while ((line = br.readLine()) != null) {
if ("886".equals(line)) {
break;
}
bw.write(line);
bw.newLine();
bw.flush();
}
// 釋放資源
s.close();
}
}
package ServerClientTCPDemo3;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class serverDemo {
public static void main(String[] args) throws IOException {
// 建立伺服器Socket對象
ServerSocket ss = new ServerSocket(12345);
// 監聽用戶端連結,傳回一個對應的Socket對象
Socket s = ss.accept();
// 接收資料
BufferedReader br = new BufferedReader(
new InputStreamReader(s.getInputStream()));
// 把資料寫入文本檔案
BufferedWriter bw = new BufferedWriter(new FileWriter("my/s.txt"));
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
// 釋放資源
bw.close();
ss.close();
}
}
3.6 TCP通信練習4
- 需求:
用戶端:資料來自于文本檔案
伺服器:接收到的資料寫入文本檔案
- 案例分析:
建立用戶端,建立輸入流對象指向檔案,從檔案循環讀取資料,每讀取一行就使用輸出流給伺服器輸出一行
建立服務端,建立輸出流對象指向檔案,從用戶端接受資料,每接受一行就給檔案中輸出一行
示例
package ServerClientTCPDemo4;
import java.io.*;
import java.net.Socket;
public class clientDemo {
public static void main(String[] args) throws IOException {
// 建立用戶端Socket對象
Socket s = new Socket("127.0.0.1", 12345);
// 封裝文本檔案的資料
BufferedReader br = new BufferedReader(new FileReader("myNet/test.java"));
// 封裝輸出流寫資料
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
// 釋放資源
br.close();
s.close();
}
}
package ServerClientTCPDemo4;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class serverDemo {
public static void main(String[] args) throws IOException {
// 建立伺服器Socket對象
ServerSocket ss = new ServerSocket(12345);
// 監聽用戶端連接配接,傳回i個對應的Socket對象
Socket s = ss.accept();
// 接收資料
BufferedReader br = new BufferedReader(
new InputStreamReader(s.getInputStream()));
// 把資料寫入檔案
BufferedWriter bw = new BufferedWriter(
new FileWriter("myNet/copy.java"));
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
// 釋放資源
bw.close();
ss.close();
}
}
3.7 TCP通信練習5
- 需求:
用戶端:資料來自于文本檔案,接收伺服器回報
伺服器:接收到的資料寫入文本檔案,給出回報
- 案例分析
建立用戶端對象,建立輸入流對象指向檔案,每讀入一行資料就給伺服器輸出一行資料,輸出結束後使用shutdownOutput()方法告知服務端傳輸結束
建立伺服器對象,建立輸出流對象指向檔案,每接受一行資料就使用輸出流輸出到檔案中,傳輸結束後。使用輸出流給用戶端回報資訊
用戶端接受服務端的回饋資訊
- 相關方法
示例
package ServerClientTCPDemo5;
import java.io.*;
import java.net.Socket;
public class clientDemo {
public static void main(String[] args) throws IOException {
// 建立用戶端Socket對象
Socket s = new Socket("127.0.0.1", 12345);
// 封裝文本檔案的資料
BufferedReader br = new BufferedReader(
new FileReader("myNet/test.java"));
// 封裝輸出流寫資料
BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(s.getOutputStream()));
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
// pubic void shutdownOutput()
s.shutdownOutput();
// 接收回報
BufferedReader brClient = new BufferedReader(
new InputStreamReader(s.getInputStream())
);
String data = brClient.readLine();
System.out.println("伺服器的回報: " + data);
// 釋放資源
br.close();
s.close();
}
}
package ServerClientTCPDemo5;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class serverDemo {
public static void main(String[] args) throws IOException {
// 建立伺服器Socket對象
ServerSocket ss = new ServerSocket(12345);
// 監聽用戶端連接配接,傳回一個對應的Socket對象
Socket s = ss.accept();
// 接收資料
BufferedReader br = new BufferedReader(
new InputStreamReader(s.getInputStream())
);
// 把資料寫入文本檔案
BufferedWriter bw = new BufferedWriter(
new FileWriter("myNet/test.java"));
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
// 給出回報
BufferedWriter bwServer = new BufferedWriter(
new OutputStreamWriter(s.getOutputStream()));
bwServer.write("檔案上傳成功");
bwServer.newLine();
bwServer.flush();
// 釋放資源
bw.close();
ss.close();
}
}
3.8 TCP通信聯系6
- 需求:
用戶端:資料來自于文本檔案,接收伺服器回報
伺服器:接收到的資料寫入文本檔案,給出回報,代碼用線程進行封裝,為每一個用戶端開啟一個線程
- 案例分析
建立用戶端對象,建立輸入流對象指向檔案,每讀入一行資料就給伺服器輸出一行資料,輸出結束後使用shutdownOutput()方法告知服務端傳輸結束
建立多線程類,在run()方法中讀取用戶端發送的資料,為了防止檔案重名,使用計數器給檔案名編号,接受結束後使用輸出流給用戶端發送回報資訊
建立服務端對象,每監聽到一個用戶端則開啟一個新的線程接受資料
用戶端接受服務端的回饋資訊
示例
package ServerClientTCPDemo6;
import java.io.*;
import java.net.Socket;
public class clientDemo {
public static void main(String[] args) throws IOException {
// 建立Socket對象
Socket s = new Socket("127.0.0.1", 12345);
// 封裝文本檔案的資料
BufferedReader br = new BufferedReader(
new FileReader("myNet/test.java"));
// 封裝輸出流寫資料
BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(s.getOutputStream()));
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
s.shutdownOutput();
// 接收回報
BufferedReader brClient = new BufferedReader(
new InputStreamReader(s.getInputStream()));
String data = brClient.readLine();
System.out.println("伺服器的回報:" + data);
// 釋放資源
br.close();
s.close();
}
}
package ServerClientTCPDemo6;
import java.io.*;
import java.net.Socket;
public class serverThread implements Runnable {
private Socket s;
public serverThread(Socket s) {
this.s = s;
}
@Override
public void run() {
try {
// 接收資料寫到文本檔案
BufferedReader br = new BufferedReader(
new InputStreamReader(s.getInputStream()));
// 解決名稱沖突問題
int count = 0;
File file = new File("myNet/test[" + count + "].java");
while (file.exists()) {
count++;
file = new File("myNet/test[" + count + "].java");
}
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
// 給出回報
BufferedWriter bwServer = new BufferedWriter(
new OutputStreamWriter(s.getOutputStream()));
bwServer.write("檔案上傳成功");
bwServer.newLine();
bwServer.flush();
// 釋放資源
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package ServerClientTCPDemo6;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class serverDemo {
public static void main(String[] args) throws IOException {
// 建立伺服器Socket對象
ServerSocket ss = new ServerSocket(12345);
while (true) {
// 監聽用戶端連接配接,傳回一個對應的Socket對象
Socket s = ss.accept();
// 為每一個用戶端開啟一個線程
new Thread(new serverThread(s)).start();
}
}
}