单线程Java Socket通信就是Server只能接受一个Client请求,当第一个Client连接后就占据了这个位置,后续Client不能再继续连接,所以需要做些改动,当Server每次接受到一个Client连接请求之后,都把处理流程放到一个独立的线程里去运行,然后等待下一个Client连接请求,这样就不会阻塞Server端接收请求了。每个独立运行的程序在使用完Socket对象之后要将其关闭。
下面是例子,客户端输入字母后由服务器端转换为大写字母,随后发回给客户端,服务器处理的时候中间让线程停止了10秒钟,便于打开多个客户端观察多线程结果。
server端:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.*;
import java.util.concurrent.*;
public class MultiThreadServer {
private int port = 6789;
private ServerSocket serverSocket;
private ExecutorService executorService;// 线程池
private final int POOL_SIZE = 10;// 单个CPU线程池大小
public MultiThreadServer() throws IOException {
serverSocket = new ServerSocket(port);
// Runtime的availableProcessor()方法返回当前系统的CPU数目.
executorService = Executors.newFixedThreadPool(Runtime.getRuntime()
.availableProcessors() * POOL_SIZE);
System.out.println("服务器启动");
}
public void service() {
while (true) {
Socket socket = null;
try {
// 接收客户连接,只要客户进行了连接,就会触发accept();从而建立连接
socket = serverSocket.accept();
executorService.execute(new Handler(socket));
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
new MultiThreadServer().service();
}
}
class Handler implements Runnable {
private Socket socket;
String clientSentence;
String capitalizedSentence;
public Handler(Socket socket) {
this.socket = socket;
}
public void run() {
try {
// 建立双向通道
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(
socket.getOutputStream());
// 从客户端得到输入并处理后发送给客户端
clientSentence = inFromClient.readLine();
// 停10秒,方便开启两个client测试多线程
Thread.sleep(10000);
capitalizedSentence = clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MultiThreadClient {
private static String IP = "127.0.0.1";
private static int PORT = 6789;
public static void main(String[] args) {
String sentence;
String modifiedSentence;
Socket clientSocket;
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(
System.in));
try {
// 与服务器建立连接
clientSocket = new Socket(IP, PORT);
// 建立双向通道
DataOutputStream outToServer = new DataOutputStream(
clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
// 从用户得到输入并发送给服务器
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
// 从服务器得到相应输出并从客户端输出
modifiedSentence = inFromServer.readLine();
System.out.println("FROM SERVER:" + modifiedSentence);
clientSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}