基于 java nio 长连接实现的聊天室

java NIO及NIO聊天室 参考链接: java NIO实例1:http://blog.chinaunix.net/uid-25808509-id-3346228.html java NIO教程之selector(一系列):http://ifeve.com/selectors/ java NIO与IO的比较:http://blog.youkuaiyun.com/keda8997110/article/details/19549 阅读详情

TCP长连接与短连接的区别

基于 java nio 长连接实现的聊天室,如果并发量大的话,可能会有线程问题。

服务端代码

package com.lp.io.socket;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class LpNioServerSocket {

    //线程安全
    private static List<SocketChannel> channels = Collections.synchronizedList( new ArrayList<SocketChannel>() );

    public static void main(String[] args) {

        HandlerSelectionKey handler = new HandlerHandlerSelectionKeyImpl();

        try {
            //创建 ServerSocketChannel
            ServerSocketChannel server = ServerSocketChannel.open();
            server.configureBlocking(false);
            server.bind(new InetSocketAddress("localhost", 12345));
            //创建 Selector
            Selector selector = Selector.open();
            server.register(selector, SelectionKey.OP_ACCEPT);
            //死循环,持续接收 客户端连接
            while(true) {
                //selector.select(); 是阻塞方法
                int keys = selector.select();
                if(keys > 0) {
                    Iterator<SelectionKey> it = selector.selectedKeys().iterator();
                    while(it.hasNext()) {
                        SelectionKey key = it.next();
                        it.remove();
                        //处理 SelectionKey
                        handler.handler(key, selector);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * SelectionKey 处理接口
     *
     */
    public static interface HandlerSelectionKey {

        public void handler(SelectionKey key, Selector selector) throws IOException;

    }

    /**
     * SelectionKey 接口 实现类
     *
     */
    public static class HandlerHandlerSelectionKeyImpl implements HandlerSelectionKey {

        @Override
        public void handler(SelectionKey key, Selector selector) throws IOException {
            int keyState = selectionKeyState(key);
            switch (keyState) {
            case SelectionKey.OP_ACCEPT:
                ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
                accept(serverSocketChannel, selector);
                break;
            case SelectionKey.OP_READ:
                SocketChannel readSocketChannel = (SocketChannel) key.channel();
                read(readSocketChannel, selector);
                break;
            }
        }
        /**
         * 获取 SelectionKey 是什么事件
         * @param key
         * @return
         */
        private int selectionKeyState(SelectionKey key) {
            if(key.isAcceptable()) {
                return SelectionKey.OP_ACCEPT;
            } else if(key.isReadable()) {
                return SelectionKey.OP_READ;
            }
            return -1;
        }

        /**
         * 接口客户端请求
         * @param serverSocketChannel
         * @param selector
         * @throws IOException
         */
        private void accept(ServerSocketChannel serverSocketChannel, Selector selector) throws IOException {
            SocketChannel socketChannel = serverSocketChannel.accept();
            socketChannel.configureBlocking(false);
            channels.add(socketChannel);
            //将 channel 注册到  Selector
            socketChannel.register(selector, SelectionKey.OP_READ);
        }

        /**
         * 读取客户端发送过来的信息
         * @param socketChannel
         * @param selector
         * @throws IOException
         */
        private void read(SocketChannel socketChannel, Selector selector) throws IOException {
            ByteBuffer readBuffer = ByteBuffer.allocate(8192);
            int readBytes = socketChannel.read(readBuffer);
            String msg = "";//客户端发送来的消息
            if(readBytes > 0) {
                 msg = new String(readBuffer.array(), 0, readBytes);
                System.out.println("客户端发送来的消息");
                System.out.println(msg);
            }
            write(socketChannel, msg);
        }

        /**
         * 响应客户端请求
         * @param socketChannel
         * @param selector
         * @throws IOException
         */
        private void write(SocketChannel socketChannel, String msg) throws IOException {
            msg = "游客" + socketChannel.hashCode()+ "\r\n    " + msg;
            //响应消息
            byte[] responseByte = msg.getBytes();
            ByteBuffer writeBuffer = ByteBuffer.allocate(responseByte.length);
            writeBuffer.put(responseByte);
            writeBuffer.flip();
            //响应客户端
            for(int i=0; i<channels.size(); i++) {
                if(!socketChannel.equals(channels.get(i))) {
                    channels.get(i).write(writeBuffer);
                }
            }
        }

    }


}

客户端代码

package com.lp.io.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class LpSocketClient1 {

    /**
     * @param args
     * @throws IOException 
     * @throws UnknownHostException 
     * @throws InterruptedException 
     */
    public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {

        final Socket socket = new Socket("localhost", 12345);
        Thread inT = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    while(true) {
                        InputStream inputStream = socket.getInputStream();
                        byte[] b = new byte[8192];
                        int readSize = inputStream.read(b);
                        System.out.println(new String(b,0,readSize));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        inT.start();
        while(true) {
            InputStreamReader stdin = new InputStreamReader(System.in);//键盘输入 
            BufferedReader bufin = new BufferedReader(stdin); 
            String str = bufin.readLine(); 
            System.out.println(str);

            OutputStream outStream = socket.getOutputStream();
            outStream.write(str.getBytes());
            outStream.flush();
        }

    }

}

启动服务端代码,然后启动多个客户端。在某个客户端代码控制台输入英文(输入中文乱码),点击回车,可以看到其他客户端控制台有信息输出。

Java NIO实现简单聊天室(GUI版) Java NIO实现简单聊天室(GUI版) 登录界面: package com.chatroom; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing 阅读详情

相关推荐

【pytorch】DataLoader(数据迭代器) 包含多种DataLoader的生成方法

本博客讲解了pytorch框架下DataLoader的多种用法,每一种方法都展示了实例,虽然有一点复杂,但是小伙伴静下心看一定能看懂哦 :),在1.1.1节介绍的三种方法中,推荐(方法三实在是过于复杂不做推荐),另外,第三节中的处理示例使用了非DataLoader的方法进行数据集处理,也可以借鉴~

学渣的博客 6万+

java socket 连续发送数据_Java AIO中连续发送的多条数据接收时连在一起的问题

刚开始学习Java网络编程,问题可能有点小白,还请见谅。我写了一个简单的Demo,运用AIO(NIO2.0)编程模型中的AsynchronousSocketChannel来发送和接收数据,在客户端与服务端之间建立一个长连接来进行通讯,然后发现当客户端连续进行多次发送时,服务端收到的数据就会连在一起,并且是随机地连在一起,感觉像是两次read之间到达的数据都被后一次read一次性读出来了,在一次测试...

weixin_35129495的博客 1082

Java 长链接示例

JAVA实现长连接(含心跳检测)Demo,基于https://blog.youkuaiyun.com/zmx729618/article/details/54378259该作者的博文实现的代码示例。

Java中 BIO vs NIO vs AIO

Java中 BIO vs NIO vs AIO 一.前言 Java中有阻塞IO、非阻塞IO。阻塞IO可以理解为“一个连接对应于一线程”。非阻塞IO可以理解为“一个请求(一个请求里面可能会有多个连接【长连接短连接】)对应于一线程”。 二.BIO BIO也称为同步阻塞IO。 同步阻塞IO模式下,服务器实现模式为一个连接对应一个线程,即:有连接请求从客户端发起时,服务器端就需要创建一个线程进行处理,如果有大量连接时,服务器就需要创建大量线程进行处理。当然这可以通过线程池机制来改善。 阻塞IO适用场景为: 连接数较

xunbaobao123的博客 301

Java实现Socket长连接和短连接

Java实现Socket长连接和短连接,实现原理可参见个人博客

迈德威视相机调用( 基于 Linux系统+ OpenCV )

迈德威视相机调用( 基于 Linux系统+ OpenCV )前言一、登录迈德威视官网,下载官方SDK二、代码调用与视频帧处理( 基于 OpenCV )总结 前言     此博客记录了迈德威视工业相机在 Linux 系统下的代码调用及其环境配置,通过 OpenCV 对视频帧进行处理。   一、登录迈德威视官网,下载官方SDK      迈德威视官网 : http://www.mindvision.com.cn/     1. 进入官网后,在服务支持中选择软件下载。    2. 选择Linux系统S.

kkkkkk0729的博客 5680

java nio socket长连接_nio实现Socket长连接和心跳

前段时间用bio方式,也就是传统io实现了socket的长连接和心跳,总觉着服务端开启多线程管理socket连接的方式过于消耗资源,数据并发的情况下可能会影响到性能,因此就尝试使用nio改进原来的代码。然而改进的过程却不像我起初设想的那般容易,可以说一波三折,原因主要是nio读写都是字节流,LZ一开始依然通过ObjectOutputStream.writeObject直接向Socket服务端发送数...

weixin_30424461的博客 1108

B0505S选型

    使用B0505S-1W已经有一段时间了,一直以来使用的是下面的电路,该电路摘自《CAN总线嵌入式开发——从入门到实战》一书。 参考金升阳的用户手册,手册上写道: 为了确保该模块能够高效可靠的工作,使用时,其输出最小负载不能小于额定负载的10%。若您所需功率确实较小,请在输出端并联一个电阻(电阻消耗功率与实际使用功率之和大于等于10%的额定功率)        由于使用该电源模...

动感小麦兜的博客 1万+

消息推送之Socket----长连接和心跳

最近学习郭霖讲的消息推送其中讲到使用原生的Socket保持长链接来实现消息的推送,这是我的短板,所以跟着仔细学习了一遍,郭神还是依旧的那么仔细那么认真,赞赞,不要骄傲要保持,而对于我就是不要急躁,要踏实做好每一点小事,加油! 废话不多说,这里附上服务器和客户端的代码,就不做解说了,这是慕课网视频教程地址:http://www.imooc.com/learn/223客户端代码如下:public cl

星光小站 2182

ubuntu 20.04系统离线安装nfs

ubuntu环境下,离线安装nfs

m0_62464865的博客 2245

SIwave仿真手册——信号完整性仿真之S参数的提取(二)

上一篇简单了讲述了软件的各个操作界面,本次博客更新关于的仿真,因为第二章完整的内容比较多,所以分成好几篇博客进行分享。

luohuo9844的博客 1万+

java nio socket长连接_基于 java nio 长连接实现的聊天室

基于 java nio 长连接实现的聊天室,如果并发量大的话,可能会有线程问题。服务端代码package com.lp.io.socket;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;impo...

weixin_33536190的博客 359

DeepSeek掘金——用DeepSeek模型构建AI 代理

在本综合指南中,我们将探讨如何利用 DeepSeek 的功能构建能够以有意义的方式理解、推理和交互的复杂 AI 代理。人工智能领域正在迅速发展,DeepSeek 的模型代表了智能 AI 代理开发的重大进步。在本综合指南中,我们将探讨如何利用 DeepSeek 的功能构建能够以有意义的方式理解、推理和交互的复杂 AI 代理。

3863

NIO Selecotr/Channel实现原理解析

目前很多高性能的Java RPC框架都是基于Netty实现的,而Netty的设计原理又离不开Java NIO。本篇笔记是对NIO核心三件套:缓冲区(Buffer)、选择器 (Selector)和通道(Channel),其中后两者实现原理的学习总结。

兴趣使然的草帽路飞 1万+

rk3568 Android12 增加 USB HOST 模式开关(二)

将原有 USB-C 改为 USB-A,并在设置中增加USB工作模式开关可以让用户选择USB端口的功能模式,例如充电、文件传输、或MIDI设备。用户能够灵活管理设备的连接方式,优化数据传输和设备兼容性。

weixin_35723192的博客 734

深度强化Q学习-基于微软AirSim仿真环境的自动驾驶案例(原理代码详解简易可行)

最近在学习《强化学习原理与Python实现》,肖智清著。参考第十二章的自动驾驶案例,写一篇总结,尽量做到简单可行,让有志于自动驾驶的小伙伴可以通过此篇博客可以管中窥豹,初步了解自动驾驶的强化学习训练过程。 本篇将自动驾驶问题转化为回合制的强化学习任务,设计以车辆观察图像和运行状态为输入的自动驾驶算法,并在AirSim仿真环境中进行训练和测试。本篇使用带经验回放和目标网络的基于深度Q网络算法设计并实现智能体,对经验回放、目标网络和深度Q学习算法进行简单介绍,并用代码实现。

shao918516的博客 8600

NIO实现聊天室

NIO概述 NIO(Non-blocking I/O,在Java领域,也称为New I/O),是一种同步非阻塞的I/O模型,也是I/O多路复用的基础,已经被越来越多地应用到大型应用服务器,成为解决高并发与大量连接、I/O处理问题的有效方式。 三大核心部分 Channel(通道) Buffer(缓冲区) Selector(多路复用器) NIO聊天室 # 服务端 package com.milla.study.netbase.expert.io.nio; import co...

hu10131013的博客 11万+

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

基于netty NIO开发的聊天室

一、为何要使用netty开发 由于之前已经用Java中的socket写过一版简单的聊天室,这里就不再对聊天室的具体架构进行细致的介绍了,主要关注于使用netty框架重构后带来的改变。对聊天室不了解的同学可以先看下我的博客(《JAVA简单聊天室的实现》) 本篇博客所使用的netty版本为4.1.36,完整工程已上传到Github(https://github.com/Alexlingl/Chat...

Alexwym的博客 3556

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Java NIO 网络编程实践:聊天室

本文主要介绍了Java NIO网络编程实践案例:聊天室的代码实现过程。

专注Java和MySQL领域知识分享 1065

NIO实现网络聊天室

1. 网络聊天室 1.1 实现客户端 public class TcpNioClient { public static void main(String[] args) throws IOException, InterruptedException { // 1. 得到一个网络通道 SocketChannel socket = SocketChannel...

qq_41424681的博客 826

NIO实现网络聊天室分析及代码实现

NIO实现网络聊天室 1. NIO完成网络编程 1.1 Selector选择器老大 Selector 选择器,网络编程使用NIO的大哥!!! 服务器可以执行一个线程,运行Selector程序,进行监听操作。 新连接, 已经连接, 读取数据,写入数据 Selector常用方法: public static Selector Open(); 得到一个选择器对象 public int s...

weixin_46292175的博客 600

NIO学习总结 附:聊天室NIO实现demo

文章目录1. 前言2. NIO 几个概念2.1 Buffer2.1.1 常用实现类2.1.2 三个属性 capacity,position和limit2.2 Channel2.2.1 Channel 基本实现2.3 Selector2.3.1 注册时有四个类型常量2.3.2 SelectionKey2.4 Pipe3. 如何使用3.1 Buffer 使用3.2 Channel + Buffer 使用3.3 Selector 使用3.4 Pipe 使用4. 聊天室示例4.1 读打印工具类ChannelUt

木秀林的博客 785

使用NIO实现聊天室

文章目录服务端客户端参考资料 服务端 package example; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.*; import java.util.Iterator; public class Gr...

勇敢的兵 879

Java知识点——NIO实现网络聊天室

NIO实现网络聊天室 1. NIO完成网络编程 1.1 Selector选择器老大 Selector 选择器,网络编程使用NIO的大哥!!! 服务器可以执行一个线程,运行Selector程序,进行监听操作。 新连接, 已经连接, 读取数据,写入数据 Selector常用方法: public static Selector Open(); 得到一个选择器对象 public int s...

qq_42581682的博客 275
上一篇: 基于Java NIO 的socket通信实例
下一篇: apache-common-pool2(配置参数详解,以及资源回收,从池中获取资源,将资源返还给池 逻辑解析)
三易的博客
博客等级 码龄15年 42粉丝 89原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值