网络编程-NIO案例 与 AIO 案例

news/2025/2/12 0:05:37/

案例说明:一个简单的群聊实现,支持重复上下线。

NIO

服务端

public class NIOServer {public static void main(String[] args) throws IOException {ServerSocketChannel serverChannel = ServerSocketChannel.open();// 初始化服务器serverChannel.bind(new InetSocketAddress(9999));Selector selector = Selector.open();serverChannel.configureBlocking(false);serverChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {// 每过两秒中来看是否有请求过来if (selector.select(2000) != 0) {System.out.println("===================");Iterator<SelectionKey> it = selector.selectedKeys().iterator();try {String ipStr = "";while (it.hasNext()) {SelectionKey next = it.next();// 建立连接if (next.isAcceptable()) {ByteBuffer bu = ByteBuffer.allocate(1024);SocketChannel channel = serverChannel.accept();channel.configureBlocking(false);channel.register(selector, SelectionKey.OP_READ, bu);ipStr = channel.getRemoteAddress().toString().substring(1);System.out.println(ipStr + "上线 ...");}// 读取数据if (next.isReadable()) {SocketChannel channel = (SocketChannel) next.channel();// 如果这个时候通道已经关闭了if (!channel.isOpen()) {next.cancel();return;}try {channel.configureBlocking(false);ByteBuffer buffer = (ByteBuffer) next.attachment();channel.read(buffer);String msg = new String(buffer.array(), 0, buffer.position());System.out.println("receive : " + msg);// 广播消息broadCast(selector, channel, msg);buffer.clear();} catch (Exception e) {System.out.println("======================发生异常进行下线操作=========");next.cancel();it.remove();continue;}}it.remove();}} catch (Exception e) {e.printStackTrace();}}}}public static void broadCast(Selector selector, SocketChannel channel, String msg) throws IOException {Set<SelectionKey> keys = selector.keys();Iterator<SelectionKey> iterator = keys.iterator();while (iterator.hasNext()) {SelectionKey next = iterator.next();SelectableChannel targetChannel = next.channel();// 如果被广播的对象连接还在if (targetChannel.isOpen()) {if (targetChannel instanceof SocketChannel && channel != targetChannel) {((SocketChannel) targetChannel).write(ByteBuffer.wrap(msg.getBytes()));}} else {// 表示通道不存在了 进行下线操作next.cancel();}}}
}

客户端

public class NIOClient {private SocketChannel channel;private String userName;private String bindIP;private int bindPort;public NIOClient(String userName, String bindIP, int bindPort) throws IOException {channel = SocketChannel.open();channel.configureBlocking(false);this.bindIP = bindIP;this.bindPort = bindPort;channel.connect(new InetSocketAddress(bindIP, bindPort));this.userName = userName;while (!channel.finishConnect()) {// 等待连接成功}}public void sendMsg(String msg) throws IOException {if (msg == "end") {channel.close();return;}msg = "from " + this.userName + " : " + msg;channel.write(ByteBuffer.wrap(msg.getBytes()));}public void receive() throws IOException {ByteBuffer buffer = ByteBuffer.allocate(1024);int size = channel.read(buffer);if(size>0){String msg=new String(buffer.array());System.out.println(msg.trim());}}
}
// Main 函数
public static void main(String[] args) throws IOException {new Thread(() -> {final NIOClient nioClient;try {nioClient = new NIOClient("one", "127.0.0.1", 9999);} catch (IOException e) {throw new RuntimeException(e);}Thread thread = new Thread(() -> {try {while (true) {nioClient.receive();Thread.sleep(3000);}} catch (IOException e) {throw new RuntimeException(e);} catch (InterruptedException e) {System.out.println("=============== 离线 ===================");}});thread.start();;System.out.println( "one pleas input : ");Scanner scanner = new Scanner(System.in);String msg = "";while (!(msg = scanner.nextLine()).equals("end")) {try {nioClient.sendMsg(msg);} catch (IOException e) {e.printStackTrace();throw new RuntimeException(e);}}thread.interrupt();}).start();
};

AIO

public class NettyServer {public static void main(String[] args) {NioEventLoopGroup boosGroup = new NioEventLoopGroup();NioEventLoopGroup workGroup = new NioEventLoopGroup();try {ServerBootstrap bootstrap = new ServerBootstrap();bootstrap.group(boosGroup, workGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true).childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel socketChannel) throws Exception {ChannelPipeline pipeline = socketChannel.pipeline();pipeline.addLast("decoder", new StringDecoder());pipeline.addLast("encoder", new StringEncoder());pipeline.addLast(new NettyChatServerHandler());}});ChannelFuture f = bootstrap.bind(9999).sync();f.channel().closeFuture().sync();} catch (Exception e) {e.printStackTrace();} finally {boosGroup.shutdownGracefully();workGroup.shutdownGracefully();System.out.println("关闭");}}
}
public class NettyChatServerHandler extends SimpleChannelInboundHandler<String> {public static List<Channel> channels = new ArrayList<>();@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {Channel channel = ctx.channel();channels.add(channel);System.out.println(channel.remoteAddress().toString().substring(1) + " online");}@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception {Channel channel = ctx.channel();for (Channel ch : channels) {if (ch != channel) {ch.writeAndFlush("["+ch.remoteAddress().toString().substring(1)+"]"+"said:"+s+"\n");}}}@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {Channel channel = ctx.channel();channels.remove(channel);System.out.println(channel.remoteAddress().toString().substring(1) + " off line");}
}
public class ChatClient {private String host;private int port;public ChatClient(String host, int port) {this.host = host;this.port = port;}public void run() {NioEventLoopGroup group = new NioEventLoopGroup();try {Bootstrap bootstrap = new Bootstrap();bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel socketChannel) throws Exception {ChannelPipeline pipeline = socketChannel.pipeline();pipeline.addLast("decoder", new StringDecoder());pipeline.addLast("encoder", new StringEncoder());pipeline.addLast(new NettyClientHandler());}});ChannelFuture sync = bootstrap.connect(new InetSocketAddress("127.0.0.1",9999)).sync();Channel channel = sync.channel();Scanner scanner = new Scanner(System.in);while (scanner.hasNextLine()) {String msg = scanner.nextLine();channel.writeAndFlush(msg + "\\r\\n").sync();}sync.channel().closeFuture().sync();} catch (Exception e) {e.printStackTrace();} finally {group.shutdownGracefully();}}
}
public class NettyClientHandler extends SimpleChannelInboundHandler<String> {@Overrideprotected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {System.out.println(s.trim());}
}

http://www.ppmy.cn/news/1361054.html

相关文章

HEVC视频编解码标准学习笔记-1

视频编解码标准H.265/HEVC&#xff08;High Efficiency Video Coding&#xff09;通过将视频数据编码为更高效格式&#xff0c;大幅改善了视频流的压缩效率。这里主要介绍Tile、Slice和CTU的定义&#xff0c;以及介绍这些技术组件之间的相互关系。 CTU&#xff08;编码树单元&…

【Vuforia+Unity】AR06-空间环境识别功能(AreaTargets)

Vuforia原理:把被识别的物体转成图、立体图、柱形图,3D模型、环境模型,然后模型生成Vuforia数据库-导入Unity-参考模型位置开始摆放数字内容,然后参考模型自动隐藏-发布APP-识别生活中实物-数字内容叠加上去! 不论你是否曾有过相关经验,只要跟随本文的步骤,你就可以成功…

西门子200SMART SB AE01的正确用法

西门子200SMART SB AE01&#xff0c;就是1路模拟量输入的SB板。信号板直接安装在 SR/ST CPU 本体正面&#xff0c;无需占用电控柜空间&#xff0c;安装、拆卸方便快捷。有些小型的系统如果只有1路模拟量输入&#xff0c;或者模块配置中恰好缺少1路模拟量输入&#xff0c;就可以…

window: C++ 获取自己写的dll的地址

我自己用C写了一个插件,插件是dll形式的,我的插件式在dll的目录下有个config文件夹,里面是我用json写的插件配置文件,当插件运行的时候我需要读取到json配置文件,所有最重要的就是如何获取dll的路径. 大概就是这么个结构, 我自己封装了一个函数.只适用于window编程,因为里面用…

Postgresql源码(124)两个事务更新同一行数据时的行为和原理分析

XactLockTableWait函数、transactionid锁的一些原理和分析 结论 更新行时&#xff0c;会根据xmax拿transactionid锁&#xff0c;等对应的事务结束。 如果结束是回滚&#xff0c;则heap_update继续更新。如果结束时提交&#xff0c;则heap_update要返回上层ExecUpdate调用EvalP…

【PostgreSQL内核学习(二十七) —— (编码转换)】

编码转换 概述处理客户端与服务器之间的字符串编码转换pg_do_encoding_conversion 函数FindDefaultConversionProc 函数FindDefaultConversion 函数 处理服务器与客户端之间的字符串编码转换两者的联系和区别 声明&#xff1a;本文的部分内容参考了他人的文章。在编写过程中&am…

Unity编辑器扩展之是否勾选Text组件BestFit选项工具(此篇教程也可以操作其他组件的属性)

想要批量化是否勾选项目预制体资源中Text组件BestFit属性&#xff08;此篇教程也可以操作其他组件的属性&#xff0c;只不过需要修改其中对应的代码&#xff09;&#xff0c;可以采用以下步骤。 1、在项目的Editor文件中&#xff0c;新建一个名为TextBestFitBatchProcessor的…

整型数组按个位值排序/最低位排序(C语言)

题目描述 给定一个非空数组&#xff08;列表&#xff09;&#xff0c;其元素数据类型为整型&#xff0c;请按照数组元素十进制最低位从小到大进行排序&#xff0c;十进制最低位相同的元素&#xff0c;相对位置保持不变。 当数组元素为负值时&#xff0c;十进制最低位等同于去除…