前言
網絡編程的過程,類似於使用 QQ 的一個點對羣的聊天。
一個服務端,多個客戶端,客戶端發送信息到服務端,當發送的是 exit 時,就關閉當前連接,關閉的方式是使得線程運行結束。
項目
其實就是2個類。
一個是服務端,如果您有興趣,可以將這個線程池的方式更改爲 ThreadPoolExecutor
這個類。
服務端代碼
package thread.v1;
import javax.net.ServerSocketFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 服務端
*/
public class Server {
public static void main(String[] args) throws IOException {
ServerSocketFactory serverSocketFactory = ServerSocketFactory.getDefault();
// 構建服務端 Socket 並設置端口
ServerSocket serverSocket = serverSocketFactory.createServerSocket(9999);
// 創建一個線程池
ExecutorService executorService = Executors.newFixedThreadPool(100);
while(true){
// 客戶端連接
Socket socket = serverSocket.accept();
executorService.submit(() -> {
try {
// 客戶端輸入
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while ((line = reader.readLine()) != null){
// 讀一行數據打印
System.out.println("客戶端來信:" + line);
if("exit".equals(line)){
System.err.println("客戶端 " + socket.getInetAddress().getHostAddress() + "正在退出連接!");
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
}
客戶端代碼
package thread.v1;
import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1", 9999);
// socket 獲取字符流
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//通過標準輸入流獲取字符流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
String line;
while((line = bufferedReader.readLine()) != null){
bufferedWriter.write(line);
bufferedWriter.newLine();
bufferedWriter.flush();
}
}
}
優化過的服務端
package thread.v1;
import javax.net.ServerSocketFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;
/**
* 服務端
*/
public class Server {
public static void main(String[] args) throws IOException {
ServerSocketFactory serverSocketFactory = ServerSocketFactory.getDefault();
// 構建服務端 Socket 並設置端口
ServerSocket serverSocket = serverSocketFactory.createServerSocket(9999);
// 創建一個線程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(60,
100,
20,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(20),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
while(true){
// 客戶端連接
Socket socket = serverSocket.accept();
threadPoolExecutor.submit(() -> {
try {
// 客戶端輸入
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while ((line = reader.readLine()) != null){
// 讀一行數據打印
System.out.println("客戶端來信:" + line);
if("exit".equals(line)){
System.err.println("客戶端 " + socket.getInetAddress().getHostAddress() + "正在退出連接!");
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
}