传统的阻塞IO,不过服务端采用线程池,一个客户端到达后起一个线程进行处理。在本实例中,服务端采用Executors管理线程池。废话少说,直接上代码:
服务端Server.java代码:
package com.test.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
public class Server {
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress(9527), 10);
final AtomicInteger count = new AtomicInteger(0);
ExecutorService pool = Executors.newCachedThreadPool(new ThreadFactory() {
public Thread newThread(Runnable r) {
return new Thread(r, "ThreadPool-new-" + count.incrementAndGet());
}
});
while(true) {
try {
final Socket clientSocket = serverSocket.accept();
pool.execute(new Runnable() {
public void run() {
String client = clientSocket.getInetAddress().getHostAddress() + ":" + clientSocket.getPort();
System.out.println(client + " received!");
System.out.println(Thread.currentThread().getName() + " handle " + client);
try {
clientSocket.setTcpNoDelay(true);
clientSocket.setReuseAddress(true);
BufferedReader bufReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter writer = new PrintWriter(clientSocket.getOutputStream());
String line = bufReader.readLine();
System.out.println(client + " say:" + line);
writer.println("received '" + line + "'");
writer.flush();
Thread.sleep(10000);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
编译:javac -d ./ Server.java
运行:java com/test/socket/Server
客户单Client.java代码:
package com.test.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1", 9527);
socket.setTcpNoDelay(true);
PrintWriter out = new PrintWriter(socket.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.println("hello world");
out.flush(); //必须flush,服务端无法收到消息
String line = reader.readLine();
System.out.println("server say : " + line);
socket.close();
}
}
编译、运行同Server端操作。
程序运行后可以快速的运行Client多次,查看服务器端的输出结果。(注意客户单的端口号是由操作系统随机分配的,根据不同的端口号可以判断是不同的客户端请求)
运行结果如下: