如何编写一个简单群聊

运用学过的Tcp网络编程可以实现一个简单的群聊,其代码如下:

服务器端的代码如下:

public class TcpServer {

    //因为ArrayList本身不是线程安全的,所以通过集合Collections.synchronizedList将其转换为一个线程安全的类

    public static List<Socket> listSocket = Collections.synchronizedList(new ArrayList<Socket>());

    public static void main(String[] args) throws IOException {

        ServerSocket ss = new ServerSocket(30000);

        while(true) {
                /*  监听客户端的连接,返回一个对应的Socket对象,这
            是一个阻塞方法,如果accept得不到一个客户端,他就一直会
            在这里等待客户端的连接,直到有一个客户端连上来才执行结束。*/
            Socket socket = ss.accept();
            listSocket.add(socket);

            new Thread(new TepServerThread(socket)).start();
        }

    }

}

TepServerThread里头的代码如下:


public class TcpServerThread implements Runnable {

    Socket socket;
    BufferedReader br;

    public TcpServerThread(Socket socket) throws IOException {
        this.socket = socket;
        br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    }

    @Override
    public void run() {

        try {
            String content;
            while ((content = read()) != null) {
                System.out.println("--------------server---------------");
                System.out.println(content);
                for (Socket s : TcpServer.listSocket) {
                    PrintWriter pw = new PrintWriter(s.getOutputStream());
                    pw.println(content);
                    pw.flush();//发送出去
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    private String read() {
        try {
            return br.readLine();
        } catch (IOException e) {
            TcpServer.listSocket.remove(socket);
        }
        return null;
    }

}

客户端代码如下:


public class TcpClient {

    public static void main(String[] args) throws IOException {

        Socket socket = new Socket("127.0.0.1", 30000);

        new Thread(new TcpClientThread(socket)).start();


        //客户端输入聊天信息,
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line;

        PrintWriter pw = new PrintWriter(socket.getOutputStream());

        while((line = br.readLine()) != null) {
            System.out.println("--------------client---------------");
            pw.println(line);
            pw.flush();//发送消息出去
        }

    }

}

TcpClientThread里头代码如下:


public class TcpClientThread implements Runnable {
    private Socket socket;
    BufferedReader br;

    public TcpClientThread(Socket socket) throws IOException {
        this.socket = socket;
        br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    }

    @Override
    public void run() {

        try {
            String content;
            while((content = br.readLine()) != null) {
                System.out.println(content + "-------------");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

感兴趣的朋友可以试试!有不当之处请指出,谢谢。可以参考这里

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以!下面是一个使用Spring Boot和Netty编写简单群聊示例: 1. 首先,创建一个Spring Boot项目,并添加Netty和Spring Boot的依赖。 2. 创建一个Netty服务器类,用于处理客户端的连接和消息发送: ```java @Component public class ChatServer { private static final int PORT = 8080; private final ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); @PostConstruct public void start() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChatServerInitializer(channelGroup)); Channel channel = bootstrap.bind(PORT).sync().channel(); channel.closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } } ``` 3. 创建一个Netty的ChannelInitializer类,用于配置ChannelPipeline: ```java public class ChatServerInitializer extends ChannelInitializer<SocketChannel> { private final ChannelGroup channelGroup; public ChatServerInitializer(ChannelGroup channelGroup) { this.channelGroup = channelGroup; } @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new ChatServerHandler(channelGroup)); } } ``` 4. 创建一个Netty的ChannelInboundHandlerAdapter类,用于处理接收到的消息并广播给所有连接的客户端: ```java public class ChatServerHandler extends ChannelInboundHandlerAdapter { private final ChannelGroup channelGroup; public ChatServerHandler(ChannelGroup channelGroup) { this.channelGroup = channelGroup; } @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { Channel incoming = ctx.channel(); // 广播通知其他客户端有新用户加入 channelGroup.writeAndFlush("[SERVER] - " + incoming.remoteAddress() + " 加入\n"); channelGroup.add(incoming); } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { Channel outgoing = ctx.channel(); // 广播通知其他客户端有用户离开 channelGroup.writeAndFlush("[SERVER] - " + outgoing.remoteAddress() + " 离开\n"); channelGroup.remove(outgoing); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { Channel incoming = ctx.channel(); System.out.println("Client: " + incoming.remoteAddress() + " 上线"); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { Channel incoming = ctx.channel(); System.out.println("Client: " + incoming.remoteAddress() + " 掉线"); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { Channel incoming = ctx.channel(); System.out.println("Client: " + incoming.remoteAddress() + " 发送消息:" + msg); // 广播消息给所有连接的客户端 channelGroup.writeAndFlush("[" + incoming.remoteAddress() + "]:" + msg + "\n"); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { Channel incoming = ctx.channel(); System.out.println("Client: " + incoming.remoteAddress() + " 异常"); cause.printStackTrace(); ctx.close(); } } ``` 5. 配置Spring Boot启动类: ```java @SpringBootApplication public class ChatApplication { public static void main(String[] args) { SpringApplication.run(ChatApplication.class, args); } } ``` 6. 运行Spring Boot应用程序,然后使用Telnet或其他工具连接到服务器的IP地址和端口号(默认为8080)。多个客户端连接到服务器后,发送的消息将被广播给所有连接的客户端。 这只是一个简单群聊示例,你可以根据实际需求进行扩展和优化。希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值