Java的NIO采用selector来轮循,还是不错,小试牛刀,下附代码

Server:

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.Iterator;public class NIOServer {private Selector selector;public void initServer(int port) throws IOException {ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();// 打开服务器套接字通道serverSocketChannel.configureBlocking(false);// 设置为非阻塞模式serverSocketChannel.socket().bind(new InetSocketAddress(port));// 绑定端口this.selector = Selector.open();// 打开选择器// 注册事件,当事件到达,selector。select()会返回,如果没有事件会一直阻塞serverSocketChannel.register(this.selector, SelectionKey.OP_ACCEPT);// 注册选择器,接受客户端连接}public void listen() throws IOException {System.out.println("服务器启动!开始轮询监听消息");while (true) {int ready = this.selector.select();if (ready == 0) {continue;}Iterator items = this.selector.selectedKeys().iterator();while (items.hasNext()) {SelectionKey key = (SelectionKey) items.next();// 删除已经选择的key,防止重复处理items.remove();// 请求连接if (key.isAcceptable()) {ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();if (serverSocketChannel == null) {continue;}SocketChannel socketChannel = serverSocketChannel.accept();//每次接受新的连接请求会产生新的通道,socketChannel.configureBlocking(false);socketChannel.write(ByteBuffer.wrap(new String("你好,客户端,连接已建立,可以开始通信!").getBytes()));//连接成功,发消息给客户端System.out.println("连接已经建立");socketChannel.register(this.selector, SelectionKey.OP_READ);//准备好接收数据} else if (key.isReadable()) {this.read(key);}}}}public void read(SelectionKey key) throws IOException {SocketChannel socketChannel = (SocketChannel) key.channel();ByteBuffer byteBuffer = ByteBuffer.allocate(100);socketChannel.read(byteBuffer);byte[] data = byteBuffer.array();String msg = new String(data).trim();if (msg.equals("close~!@#$%")) {//收到关闭指令,发送确认关闭的指令给客户端,结束自身通道ByteBuffer sendBuffer = ByteBuffer.wrap(new String("bye close").getBytes());while (sendBuffer.hasRemaining()) {socketChannel.write(sendBuffer);}socketChannel.close();System.out.println("已经关闭");} else {System.out.println("server Receive:" + msg);//服务器收到任何消息都会给客户端发送"收到"socketChannel.write(ByteBuffer.wrap(new String("收到!").getBytes()));}}public static void main(String[] args) {NIOServer server = new NIOServer();try {server.initServer(1377);server.listen();} catch (IOException e) {e.printStackTrace();}}
}

  Client:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;public class NIOClient {private Selector selector;//初始化public void initClient(String ipAddress, int port) throws IOException {SocketChannel socketChannel = SocketChannel.open();//打开套接字通道socketChannel.configureBlocking(false);//非阻塞this.selector = Selector.open();//打开选择器socketChannel.connect(new InetSocketAddress(ipAddress, port));//指定ip地址和端口号用于连接socketChannel.register(this.selector, SelectionKey.OP_CONNECT);//通道注册到选择器中,用于连接}//监听public void listen() throws IOException {while (true) {//当客户端关闭的时候需要结束轮循的动作,这样程序才会结束if (!this.selector.isOpen()) {return;}int ready = this.selector.select();//这个才是真正的轮循啦,得到通道if (ready == 0) {continue;//如果selector中没有SocketChannel,直接开始下一次咯 }Iterator items = this.selector.selectedKeys().iterator();while (items.hasNext()) {SelectionKey key = (SelectionKey) items.next();items.remove();//防止重复处理if (key.isConnectable()) {//连接System.out.println("正在连接,连接成功后,服务器会返回结果!");SocketChannel socketChannel = (SocketChannel) key.channel();// 如果正在连接,则完成连接if (socketChannel.isConnectionPending()) {socketChannel.finishConnect();}socketChannel.register(this.selector, SelectionKey.OP_READ);//重新注册该通道,用于读取数据} else if (key.isReadable()) {//读取this.read(key);}}}}/****************************************************//** 客户端关闭思路* 客户端                            服务器* * 用户输入bye,需要关闭客户端* * "close~!@#$%"   ->           "close~!@#$%"                               约定好的内容("close~!@#$%")*                    * "bye close" <-               "bye close"     ----->服务器通道关闭                      约定好的内容("bye close")* * 客户端通道关闭                    服务器还可以接受别的请求* */public void read(SelectionKey key) throws IOException {SocketChannel socketChannel = (SocketChannel) key.channel();ByteBuffer receiveBuffer = ByteBuffer.allocate(100);socketChannel.read(receiveBuffer);byte[] data = receiveBuffer.array();String msg = new String(data).trim();if (msg.equals("bye close")) {//客户端和服务器约定关闭,收到服务器响应后可以关闭System.out.println("关闭");socketChannel.close();this.selector.close();return;}System.out.println("client receive:" + msg);BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));String readMsg = reader.readLine();ByteBuffer sendBuffer = ByteBuffer.allocate(256);sendBuffer.clear();if(readMsg.equals("bye")){//告诉服务器,准备要撤退,当服务器返回bye close,关闭通道和选择器System.out.println("准备关闭");sendBuffer.put("close~!@#$%".getBytes());sendBuffer.flip();}else{sendBuffer.put(readMsg.getBytes());sendBuffer.flip();}while (sendBuffer.hasRemaining()) {socketChannel.write(sendBuffer);}}public static void main(String[] args) {NIOClient client = new NIOClient();try {client.initClient("127.0.0.1", 1377);client.listen();} catch (IOException e) {e.printStackTrace();}}
}

  客户端可开启多个,用于连接服务器端,亲测可用,有问题联系作者,xusong1313@qq.com

业务逻辑可自己完善,其实建议的搭建不难

转载于:https://www.cnblogs.com/weiki/p/4465958.html

Java NIO初试相关推荐

  1. java NIO详解

    http://zalezone.cn/2014/09/17/NIO%E7%B2%BE%E7%B2%B9/ 1. 前言 我们在写java程序的时候,为了进行优化,把全部的精力用在了处理效率上,但是对IO ...

  2. java nio设计模式_Java NIO:浅析I/O模型

    也许很多朋友在学习NIO的时候都会感觉有点吃力,对里面的很多概念都感觉不是那么明朗.在进入Java NIO编程之前,我们今天先来讨论一些比较基础的知识:I/O模型.下面本文先从同步和异步的概念 说起, ...

  3. java语言的实现机制_JAVA语言之Java NIO的工作机制和实现原理介绍

    本文主要向大家介绍了JAVA语言之Java NIO的工作机制和实现原理介绍,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. 前言 本文只简单介绍NIO的原理实现和基本工作流程 I/O和 ...

  4. java大文件读写操作,java nio 之MappedByteBuffer,高效文件/内存映射

    http://langgufu.iteye.com/blog/2107023 java处理大文件,一般用BufferedReader,BufferedInputStream这类带缓冲的Io类,不过如果 ...

  5. Java NIO系列教程(二) Channel

    为什么80%的码农都做不了架构师?>>>    Java NIO的通道类似流,但又有些不同: 既可以从通道中读取数据,又可以写数据到通道.但流的读写通常是单向的. 通道可以异步地读写 ...

  6. 11 Java NIO Non-blocking Server-翻译

    尽管你对Java NIO的工作原理很了解,但是设计一个非阻塞的服务器仍然困难.与阻塞的IO相比,非阻塞的IO也包含一些挑战.这里将会讨论一些非阻塞服务器所面临的一些挑战,以及一些可行的方案. 查找关于 ...

  7. Java NIO系列教程(六) Selector

    Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件.这样,一个单独的线程可以管理多个channel,从而管理多个网络连接. 下面是 ...

  8. Java NIO使用及原理分析(三)

    2019独角兽企业重金招聘Python工程师标准>>> 转载自:李会军•宁静致远 在上一篇文章中介绍了缓冲区内部对于状态变化的跟踪机制,而对于NIO中缓冲区来说,还有很多的内容值的学 ...

  9. java nio 写事件_Java NIO

    java Nio Selector 选择器 Buffer 缓冲器 Channel 通道 Selector是NIO的核心,是channel的管理者,通过执行select()阻塞方式,监听是否有chann ...

  10. 万字长文:助你攻破 JAVA NIO 技术壁垒

    本文来源:https://honeypps.com/java/java-nio-quick-start/ 现在使用NIO的场景越来越多,很多网上的技术框架或多或少的使用NIO技术,譬如Tomcat,J ...

最新文章

  1. 关闭Windows 2000/XP/2003默认共享
  2. LA3027简单带权并查集
  3. 【Android 逆向】Linux 文件权限 ( Linux 权限简介 | 系统权限 | 用户权限 | 匿名用户权限 | 读 | 写 | 执行 | 更改组 | 更改用户 | 粘滞 )
  4. hadoop hive安装手记(转)
  5. mysql dba系统学习(7)二进制日志binlog之三
  6. 重温c语言之环境变量
  7. Java设计模式之策略模式---写的比较有趣,推荐大家看看
  8. Jerry Wang 2014年1月3日top liked SCN博客
  9. javascript --- 几个其他的跨域技术(图像Ping、JSONP、Comet)
  10. 移植opencv3.20到3556AV100
  11. 20155222 2016-2017-2 《Java程序设计》第8周学习总结
  12. VC++的学习(基于VS2008)——windows程序内部运行机制
  13. 2019 年编写现代 JavaScript 代码的5个小技巧
  14. Affinity Publisher for Mac排版设计工具
  15. 管理感悟:一种人才分类
  16. 硬件知识:打印机常见的故障及维护,值得收藏!
  17. HTML5的文档声明
  18. 快恢复二极管工作原理及使用
  19. 永磁同步电机的矢量控制策略(八)一一一仿真模型搭建与源代码
  20. 用python画年度和月度的日历图

热门文章

  1. htc xv6950 刷机方法
  2. 【Hadoop学习笔记】大数据框架原理及主要工具概述
  3. 计算机网络CRC冗余码的计算
  4. 微信公众号内置浏览器缓存清理
  5. pfamscan 的使用_48个在线分析使用工具
  6. 【COS】函数使用技巧
  7. JDK7官方下载地址
  8. ideal上初写mapreduce程序出现的报错信息解决
  9. 亚马逊测评账号关联因素有哪些?
  10. 单片机STM32低功耗