构建一个最基本的服务器端和客户端连接,因为网络的读写操作都是使用标准IO,所以通常使用的是Socket处理机制来实现。假如要实现一个可以为多个客户端响应的服务器,服务器端为每一个建立了连接的客户端分配一个线程,每一个线程只为一个客户端连接服务,这种多线程的服务器开发是十分常见的,它的简单实现如下。
多线程服务器简单实现
要建立能处理多客户端连接处理的服务器,需要一个线程池,为每一个提交建立连接请求的客户端都创建一个线程来为它服务即可:
package com.justin.multithreadserver;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MultiThreadServerDemo {
// 服务器端中实现多线程的线程池
private static ExecutorService threadPool = Executors.newCachedThreadPool();
//监听读取客户端数据类
static class ReadClientData implements Runnable {
Socket clientSocket; // 获取该客户端连接
//构造方法初始化
public ReadClientData(Socket clientSocket) {
this.clientSocket = clientSocket;
}
@Override
public void run() {
BufferedReader bufferedRead = null;
PrintWriter printWrite = null;
InputStreamReader streamRead = null;
String readData = null; //保存每读到一行的数据
try {
streamRead = new InputStreamReader(clientSocket.getInputStream());
bufferedRead = new BufferedReader(streamRead);
printWrite = new PrintWriter(clientSocket.getOutputStream());
//开始读客户端发来的数据
while ((readData = bufferedRead.readLine()) != null) {
printWrite.println(readData); //输出读到的数据
}
//回发客户端确认连接信息
printWrite.write("建立连接成功.\r\n");
printWrite.flush(); // 将缓冲区的数据输出,刷新缓冲区
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bufferedRead != null) {
bufferedRead.close();
}
if(printWrite != null) {
printWrite.close();
}
clientSocket.close(); //关闭客户端连接
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@SuppressWarnings("resource")
//服务器中的主线程
public static void main(String[] args) {
ServerSocket server = null;
Socket clientSocket = null;
try {
server = new ServerSocket(5000); //端口号5000
} catch (IOException e) {
e.printStackTrace();
}
//开始死循环监听客户端发来的请求
while (true) {
try {
clientSocket = server.accept(); //accept()方法会阻塞当前线程,等待客户端发来的请求
System.out.println(clientSocket.getRemoteSocketAddress() + " succeed connect.");
ReadClientData readThread = new ReadClientData(clientSocket); // 为这个客户端连接开启读数据线程
threadPool.execute(readThread); // 为该客户端服务的线程提交到线程池执行
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
第18到23行