Socket学习(一):控制台聊天demo

发布于:2025-02-11 ⋅ 阅读:(44) ⋅ 点赞:(0)

实现效果

客户端连接服务端后,可在控制台输入要发送的消息,服务端收到消息后自动回复消息并将消息转发给所有连接上的客户端:
在这里插入图片描述

在这里插入图片描述
服务端收到消息并回复
在这里插入图片描述
客户端1发送消息并接收服务端的回复
在这里插入图片描述
客户端2接收服务端转发的消息

源码

SocketServer:

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class SocketServer {

    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(1024);
            Map<String, Socket> clientMap = new HashMap<>(); // 存储客户端的socket集合,key为ip+port,value为socket对象
            log.info("服务已启动,等待客户端链接");
            while (true) {
                Socket socket = serverSocket.accept();
                String ip = socket.getInetAddress().getHostAddress();
                int port = socket.getPort();
                log.info("客户端已链接,ip:{},端口:{}", ip, port);
                String key = ip + port; // 创建客户端的key
                clientMap.put(key, socket);
                // 启动一个线程,用于读取客户端发送的数据
                new Thread(() -> {
                    while (true) {
                        try {
                            InputStream inputStream = socket.getInputStream();
                            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                            String data = bufferedReader.readLine();
                            log.info("收到端口号为:{} 客户端的消息:{}", port, data);

                            // 遍历客户端集合,将消息转发给所有客户端
                            clientMap.forEach((k, v) -> {
                                try {
                                    OutputStream outputStream = v.getOutputStream();
                                    PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
                                    printWriter.println(socket.getPort() + ":" + data);
                                    printWriter.flush();
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            });
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

SocketClient:

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

@Slf4j
public class SocketClient {
    public static void main(String[] args) {
        Socket socket = null;
        try {
            // 连接服务端
            socket = new Socket("127.0.0.1", 1024);
            log.info("当前客户端端口为:{}", socket.getLocalPort());

            OutputStream outputStream = socket.getOutputStream();
            PrintWriter printWriter = new PrintWriter(outputStream);
            System.out.println("请输入要发送的数据:");
            Scanner scanner = new Scanner(System.in);

            // 启动一个线程,用于接收服务器发送的数据
            new Thread(() -> {
                while (true) {
                    String input = scanner.nextLine(); // 读取用户键盘输入的数据
                    printWriter.println(input);
                    printWriter.flush();
                }
            }).start();

            // 再启动一个线程,用于接收服务器回复的数据
            InputStream inputStream = socket.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            new Thread(() -> {
                while (true) {
                    try {
                        String data = bufferedReader.readLine();
                        System.out.println("收到服务端回复的消息:" + data);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到