tcp实现服务端接收多个客户端消息,原理:主线程使用while死循环接收socket连接,为每个客户端的socket通信管道分配一个子线程接收
引入线程池 (创建固定数量的线程,避免产生过多线程,消耗资源)
客户端
public class ClientDemo {
public static void main(String[] args) {
try {
System.out.println("----客户端----");
//1.创建Socket通信管道请求有服务端的连接,端口号为6666
Socket socket = new Socket("127.0.0.1",6666);
//2.从Socket通信管道中得到一个字节输出流 负责发送数据
OutputStream os = socket.getOutputStream();
//3.把低级的字节流包装成打印流
PrintStream ps = new PrintStream(os);
Scanner sc = new Scanner(System.in);
while(true){
System.out.println("请输入:");
String msg = sc.nextLine();
ps.println(msg);
ps.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务端
public class SeverDemo {
/*
线程池参数
参数一:核心线程
参数二:最大限制数量
参数三:临时线程空闲时间
参数四:临时线程空闲单位
参数五:任务队列
参数六:线程工厂,创建线程
参数七:任务拒绝策略
*/
//使用静态变量记住一个线程池对象
private static ExecutorService pool = new ThreadPoolExecutor(3,5,6,
TimeUnit.SECONDS,new ArrayBlockingQueue<>(2),
Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) {
try {
System.out.println("----服务端----");
//1.注册端口
ServerSocket serverSocket = new ServerSocket(6666);
//定义一个死循环由主线程负责不断接收客户端的socket管道连接
while (true) {
//2.每接收到一个客户端的socket管道,交给一个独立的子线程
Socket socket = serverSocket.accept();
System.out.println(socket.getRemoteSocketAddress() + "上线");
//任务对象负责读取消息
Runnable target = new ServerReaderRunnable(socket);
pool.execute(target);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
线程池处理Runnable任务
public class ServerReaderRunnable implements Runnable {
private Socket socket;
public ServerReaderRunnable(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
//3.从Socket通信管道中得到一个字节输入流
InputStream is = socket.getInputStream();
//4.把字节输入流包装成缓冲字符输入流进行消息的接收
BufferedReader br = new BufferedReader(new InputStreamReader(is));
//5.按照行读取消息
String msg;
while ((msg = br.readLine()) != null){
System.out.println(socket.getRemoteSocketAddress() + "说了 : " + msg);
}
} catch (IOException e) {
System.out.println(socket.getRemoteSocketAddress() + "下线");
}
}
}