服务端
package example.server;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ServerApplication {
private static int port =80;
// 可接受请求队列的最大长度
private static int backlog=100;
// 绑定到本机的IP地址
private static String bindAddr = "127.0.0.1";
//socket字典列表
private static Map<String,BufferedWriter> nodes = new ConcurrentHashMap<>();
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(port, backlog, InetAddress.getByName(bindAddr));
ExecutorService es = Executors.newFixedThreadPool(10);
while(true){
//发生阻塞,等待客户端连接
Socket sc = ss.accept();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(sc.getOutputStream(),"UTF-8"));
nodes.put(sc.getInetAddress().getHostName()+":"+sc.getPort(),writer);
System.out.println("成功建立一个新的会话["+"客户端:"+sc.getPort()+"]");
BroadcastTask task = new BroadcastTask(sc,nodes);
es.execute(task);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
消息广播
package example.server;
import java.io.*;
import java.net.Socket;
import java.util.Map;
public class BroadcastTask implements Runnable {
private Socket socket;
private Map<String,BufferedWriter> nodes;
public BroadcastTask(Socket socket, Map<String,BufferedWriter> nodes) {
this.socket = socket;
this.nodes = nodes;
}
@Override
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8"));
String msg = "您好,"+ socket.getPort() + ",欢迎来到聊天室! ";
writer.write(msg);
writer.newLine();
writer.flush();
while (!socket.isClosed()){
//接收到的消息
String content = reader.readLine();
String message = "[" + "客户端"+ ":" + socket.getPort()+"]:"+content;
if(content.toLowerCase().equals("quit")||content.toLowerCase().equals("exit")){
nodes.remove(socket.getInetAddress().getHostName() + ":" + socket.getPort());
message = "**系统通知**:用户[" + socket.getPort() + "]退出聊天室";
System.out.println(message);
reader.close();
socket.close();
}
//广播消息
for(Map.Entry<String,BufferedWriter> entry:nodes.entrySet()){
writer = entry.getValue();
writer.write(message);
writer.newLine();
writer.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端
package example.client;
import java.io.*;
import java.net.Socket;
public class ClientApplication {
// 监听端口号
private static final int port = 80;
// 绑定到本机的IP地址
private static final String bindAddr = "127.0.0.1";
public static void main(String[] args) {
try {
System.out.println("正在连接Socket服务器...");
Socket socket = new Socket(bindAddr,port);
Thread t1 = new Thread(() -> {
try {
//获取socket的输入流
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
//接收到的消息
String content;
while (true) {
if(socket.isClosed()){
break;
}
content=reader.readLine();
System.out.println(content);
}
} catch (IOException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
try {
BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8"));
BufferedReader inputReader=new BufferedReader(new InputStreamReader(System.in));
String msg;
while(true){
System.out.println("请输入要发送的信息(回车发送):");
msg=inputReader.readLine();
writer.write(msg);
writer.newLine();
writer.flush();
if(msg.toLowerCase().equals("exit")||msg.toLowerCase().equals("quit")){
System.out.println("Bye bye!");
socket.close();
System.exit(0);
}
}
} catch (IOException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
参考资料
[01] 简易版聊天系统实现 Socket VS NIO两种实现方式
[02] Socket编程之聊天室
[03] NIO网络编程实战之简单多人聊天室
[04] NIO 聊天室代码实现
[05] Java NIO示例:多人网络聊天室
[06] Java NIO实战之聊天室
微信扫一扫关注公众号
点击链接加入群聊
https://jq.qq.com/?_wv=1027&k=5eVEhfN
软件测试学习交流QQ群号:511619105