一共有三个类,源码在最后,以下是一 一 分析:
匿名内部类构建线程
/**
* @author thx
* @description 匿名内部类消息线程
* @yyds: thx yyds
* @date 2021/9/23 9:38
*/
class MsgThread extends Thread {
private DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
// 当前客户端
private Socket socket;
// 构造器
public MsgThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// 接受客户端信息
try {
while (true) {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));
// 这里注意,匿名内部类的变量都是 final 的,不可被改变
final String msg = reader.readLine();
// 判断是群聊还是私聊
if (msg.contains("-")) {
//是私聊,通过 lambda 和 流,找到单独发送的端口号的 socket 对象
clients.stream().filter((c) -> c.getPort() == Integer.parseInt(msg.split("-")[0])).forEach((s) -> {
try {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream(), "utf-8"));
writer.write(msg + "\n");
writer.flush();
serverSendOne(msg, s);
} catch (IOException e) {
e.printStackTrace();
}
});
//是群聊,直接对所有发东西消息即可
} else {
serverSendAll(msg);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务端分析完了,然后是客户端,其实客户端就是输入消息,得到消息的过程:
接受数据和发送数据都是死循环
源码:
聊天室类,新建聊天服务:
public class ChatRoom {
public static void main(String[] args) throws IOException {
new ChatRoomServer().start();
}
}
客户端类,客户端接收消息给服务端,服务端再返回给各个客户端
public class ChatRoomClient {
private Socket socket;
private static DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
// 构造器
public ChatRoomClient() {
try {
socket = new Socket("localhost", 12345);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("客户端" + socket.getPort() + "已经启动");
}
public void start() {
// 发送消息
new ClientSendThread().start();
// 接收消息
new ClientReceiveThread().start();
}
// 专门负责发送消息
private class ClientSendThread extends Thread {
@Override
public void run() {
try {
System.out.println("如果直接发言,就是给所有人");
System.out.println("私聊格式 port-聊天内容 ");
Scanner sc = new Scanner(System.in);
while (true) {
String msg = sc.next();
// 需要向所有的用户发消息
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "utf-8"));
bufferedWriter.write(msg + "\n");
bufferedWriter.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 专门负责接收消息
private class ClientReceiveThread extends Thread {
@Override
public void run() {
try {
while (true) {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));
System.out.println("客户端发送 " + reader.readLine() + " 时间" + format.format(new Date()));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new ChatRoomClient().start();
}
}
服务端核心部分:
public class ChatRoomServer {
private static DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
private ServerSocket serverSocket;
// 定义一个容器,存放所有的客户端
private List<Socket> clients;
//定义构造器,初始化信息
public ChatRoomServer() {
// 创建服务器
try {
serverSocket = new ServerSocket(12345);
// 服务器已经启动
System.out.println("服务器[" + serverSocket.getLocalPort() + "]启动成功,等待客户访问");
clients = new ArrayList<>();
} catch (IOException e) {
e.printStackTrace();
}
}
public void start() throws IOException {
// 等待客户端访问
while (true) {
Socket socket = serverSocket.accept();
clients.add(socket);
// 开始启动发送消息线程
new MsgThread(socket).start();
// 判断是群聊还是私聊
serverSendAll("用户【" + socket.getPort() + "】进入聊天室");
}
}
public void serverSendAll(String msg) {
for (Socket client : clients) {
try {// 开始向客户端发送信息
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(client.getOutputStream(), "utf-8"));
bufferedWriter.write(msg + "\n");
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void serverSendOne(String msg, Socket socket) {
try {// 开始向客户端发送信息
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "utf-8"));
bufferedWriter.write(msg + "\n");
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @author thx
* @description 匿名内部类消息线程
* @yyds: thx yyds
* @date 2021/9/23 9:38
*/
class MsgThread extends Thread {
private DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
// 当前客户端
private Socket socket;
public MsgThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// 接受客户端信息
try {
while (true) {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));
// String msg = "客户端[" + socket.getPort() + "]发送 " + reader.readLine() + " 时间" + format.format(new Date());
final String msg = reader.readLine();
// 判断是群聊还是私聊
if (msg.contains("-")) {
clients.stream().filter((c) -> c.getPort() == Integer.parseInt(msg.split("-")[0])).forEach((s) -> {
try {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream(), "utf-8"));
writer.write(msg + "\n");
writer.flush();
serverSendOne(msg, s);
} catch (IOException e) {
e.printStackTrace();
}
});
} else {
serverSendAll(msg);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}