- 服务器端:
package socketClient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 分发数据的服务端
* @author Heying
*
*/
public class Server {
private ServerSocket serversocket; // 服务端的socket
private ExecutorService threadPoll; // 线程池
private List<PrintWriter> allOut; // 广播集合
private Queue<String> messageQueue; // 放客户端的数据
/*
* 1.初始化端口
* 2.初始化线程池
* 3.初始化客户端的数据流
* 4.初始化消息队列
*/
public Server() {
try {
serversocket = new ServerSocket(8086); //1.
threadPoll = Executors.newCachedThreadPool(); //2. 初始化线程池
allOut = new ArrayList<PrintWriter>(); //3.初始共享集合
messageQueue = new LinkedList<String>(); //4. 初始化消息队列
} catch (IOException e) {
e.printStackTrace();
System.err.println("初始化失败!!!");
}
}
/*
* 启用客户端的方法
*/
public void start(){
try {
Runnable sendHandler = new sendMessageHandler();
Thread t = new Thread(sendHandler);
t.setDaemon(true);
t.start();
while(true){
System.out.println("等待客户端连接....");
Socket socket = serversocket.accept();
System.out.println("一个客户端连接!");
/*
* 当一个客户端连接后,启动一个线程
* 将该客户端的Socket传入。
* 使用线程来并发处理客户端的交互。
*
*/
Runnable handler = new ClientHandler(socket);
threadPoll.execute(handler); // 将任务交给线程池去处理
// Thread t1 = new Thread(handler);
// t1.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 向共享集合中添加新的输出流
*/
public synchronized void addOut(PrintWriter out){
allOut.add(out);
}
/**
* 将给定的输出流从共享集合中删除
* @param out
*/
public synchronized void removeOut(PrintWriter out){
allOut.remove(out);
}
public synchronized void sendMessageToAllClent(String message){
for(PrintWriter out:allOut){
out.println(message);
}
}
public static void main(String[] args) {
new Server().start();
}
/**
*
*/
class ClientHandler implements Runnable{
private Socket socket;
public ClientHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
PrintWriter pw = null;
try {
OutputStream os = socket.getOutputStream();// 创建客户端输出流 得到数据广播
OutputStreamWriter osp = new OutputStreamWriter(os,"UTF-8");
pw = new PrintWriter(osp,true);
// 1.将客户端的输出流放入共享集合
addOut(pw);
System.out.println("当前在线人数:"+allOut.size());
// 2.读取客户端的数据
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is,"UTF-8");
BufferedReader br = new BufferedReader(isr);
String message = null;
while( (message = br.readLine())!= null){
messageQueue.offer(message);
}
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
System.out.println("一个客户端下线!!!");
// 客户端从队列中删除
removeOut(pw);
System.out.println("在线人数>>> "+allOut.size());
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 接受到客户端的信息,然后转发
* @author Heying
*
*/
class sendMessageHandler implements Runnable{
@Override
public void run() {
String message = null;
while(true){
if(messageQueue.size() > 0){
message = messageQueue.poll();
sendMessageToAllClent(message);//转发
}else{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
2.客户端
package socketClient;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
* 接受发送的客户端
* @author Heying
*
*/
public class Client {
private Socket socket;
/*
* 初始化
* 1.服务器的IP地址
* 2.服务器的端口
*/
public Client() {
try {
socket = new Socket("localhost",8086); // 主机和端口
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* 启用客户端
*/
public void start(){
try {
Runnable hadler = new GetServerMessageHandler();
Thread t = new Thread(hadler);
t.start();
OutputStream out = socket.getOutputStream(); //获取服务端发送的数据流(输出流)
OutputStreamWriter opsw = new OutputStreamWriter(out,"UTF-8"); // 直接流-> 字符流 设置字符集
PrintWriter pw = new PrintWriter(opsw, true);
Scanner sc = new Scanner(System.in); // 设置键盘输入
while(true){
String message = sc.nextLine(); // 读取一行输入
pw.println(message); //
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Client().start();
}
/**
* 获取服务器发送过来的数据
* @author Heying
*
*/
class GetServerMessageHandler implements Runnable{
@Override
public void run() {
try {
InputStream in = socket.getInputStream(); // 获取到输入流 获取服务器的数据
InputStreamReader isr = new InputStreamReader(in,"UTF-8"); // 字符集
BufferedReader br = new BufferedReader(isr);
String message = null;
while((message = br.readLine()) != null ){
System.out.println(">>> "+message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}