服务器

  1. package com.java.xiong.Net17;
  2. import java.io.IOException;
  3. import java.net.InetSocketAddress;
  4. import java.nio.ByteBuffer;
  5. import java.nio.channels.Channel;
  6. import java.nio.channels.SelectionKey;
  7. import java.nio.channels.Selector;
  8. import java.nio.channels.ServerSocketChannel;
  9. import java.nio.channels.SocketChannel;
  10. import java.nio.charset.Charset;
  11. public class NServer {
  12. // 用于检测所有的Channel状态的selector
  13. private Selector selector = null;
  14. static final int PORT = 30000;
  15. // 定义实现编码、解码的字符串集对象
  16. private Charset charse = Charset.forName("GBK");
  17. public void init() throws IOException {
  18. selector = Selector.open();
  19. // 通过open方法来打开一个未绑定的ServerSocketChannel是咧
  20. ServerSocketChannel server = ServerSocketChannel.open();
  21. InetSocketAddress isa = new InetSocketAddress("127.0.0.1", PORT);
  22. // 将该ServerSocketChannel绑定到指定的IP地址
  23. server.bind(isa);
  24. // 设置serverSocket已非阻塞方式工作
  25. server.configureBlocking(false);
  26. // 将server注册到指定的selector对象
  27. server.register(selector, SelectionKey.OP_ACCEPT);
  28. while (selector.select() > 0) {
  29. // 一次处理selector上的每个选择的SelectionKey
  30. for (SelectionKey sk : selector.selectedKeys()) {
  31. // 从selector上已选择的Kye集中删除正在处理的SelectionKey
  32. selector.selectedKeys().remove(sk);
  33. // 如果sk对应的Channel包含客户端的连接请求
  34. if (sk.isAcceptable()) {
  35. // 调用accept方法接收连接,产生服务器段的SocketChennal
  36. SocketChannel sc = server.accept();
  37. // 设置采用非阻塞模式
  38. sc.configureBlocking(false);
  39. // 将该SocketChannel注册到selector
  40. sc.register(selector, SelectionKey.OP_READ);
  41. }
  42. // 如果sk对应的Channel有数据需要读取
  43. if (sk.isReadable()) {
  44. // 获取该SelectionKey对银行的Channel,该Channel中有刻度的数据
  45. SocketChannel sc = (SocketChannel) sk.channel();
  46. // 定义备注执行读取数据源的ByteBuffer
  47. ByteBuffer buff = ByteBuffer.allocate(1024);
  48. String content = "";
  49. // 开始读取数据
  50. try {
  51. while (sc.read(buff) > 0) {
  52. buff.flip();
  53. content += charse.decode(buff);
  54. }
  55. System.out.println("读取的数据:" + content);
  56. // 将sk对应的Channel设置成准备下一次读取
  57. sk.interestOps(SelectionKey.OP_READ);
  58. }
  59. // 如果捕获到该sk对银行的Channel出现了异常,表明
  60. // Channel对应的Client出现了问题,所以从Selector中取消
  61. catch (IOException io) {
  62. // 从Selector中删除指定的SelectionKey
  63. sk.cancel();
  64. if (sk.channel() != null) {
  65. sk.channel().close();
  66. }
  67. }
  68. // 如果content的长度大于0,则连天信息不为空
  69. if (content.length() > 0) {
  70. // 遍历selector里注册的所有SelectionKey
  71. for (SelectionKey key : selector.keys()) {
  72. // 获取该key对应的Channel
  73. Channel targerChannel = key.channel();
  74. // 如果该Channel是SocketChannel对象
  75. if (targerChannel instanceof SocketChannel) {
  76. // 将读取到的内容写入该Channel中
  77. SocketChannel dest = (SocketChannel) targerChannel;
  78. dest.write(charse.encode(content));
  79. }
  80. }
  81. }
  82. }
  83. }
  84. }
  85. }
  86. public static void main(String [] args) throws IOException{
  87. new NServer().init();
  88. }
  89. }

客户端

  1. package com.java.xiong.Net17;
  2. import java.io.IOException;
  3. import java.net.InetSocketAddress;
  4. import java.nio.ByteBuffer;
  5. import java.nio.channels.SelectionKey;
  6. import java.nio.channels.Selector;
  7. import java.nio.channels.SocketChannel;
  8. import java.nio.charset.Charset;
  9. import java.util.Scanner;
  10. public class NClient {
  11. //定义检测Sockethannel的Selector对象
  12. private Selector  selector=null;
  13. static final int PORT=30000;
  14. //定义处理编码的字符集
  15. private Charset charset=Charset.forName("GBK");
  16. //客户端SocketChannel
  17. private SocketChannel sc=null;
  18. public void init() throws IOException{
  19. selector=Selector.open();
  20. InetSocketAddress isa=new InetSocketAddress("127.0.0.1", PORT);
  21. //调用open的静态方法创建连接指定的主机的SocketChannel
  22. sc=SocketChannel.open(isa);
  23. //设置该sc已非阻塞的方式工作
  24. sc.configureBlocking(false);
  25. //将SocketChannel对象注册到指定的Selector
  26. sc.register(selector, SelectionKey.OP_READ);
  27. //启动读取服务器数据端的线程
  28. new ClientThread().start();
  29. //创建键盘输入流
  30. Scanner scan=new Scanner(System.in);
  31. while(scan.hasNextLine()){
  32. //读取键盘的输入
  33. String line=scan.nextLine();
  34. //将键盘的内容输出到SocketChanenel中
  35. sc.write(charset.encode(line));
  36. }
  37. }
  38. //定义读取服务器端的数据的线程
  39. private class ClientThread extends Thread{
  40. @Override
  41. public void run() {
  42. try{
  43. while(selector.select()>0){
  44. //遍历每个有可能的IO操作的Channel对银行的SelectionKey
  45. for(SelectionKey sk:selector.selectedKeys()){
  46. //删除正在处理的SelectionKey
  47. selector.selectedKeys().remove(sk);
  48. //如果该SelectionKey对应的Channel中有可读的数据
  49. if(sk.isReadable()){
  50. //使用NIO读取Channel中的数据
  51. SocketChannel sc=(SocketChannel)sk.channel();
  52. String content="";
  53. ByteBuffer bff=ByteBuffer.allocate(1024);
  54. while(sc.read(bff)>0){
  55. sc.read(bff);
  56. bff.flip();
  57. content+=charset.decode(bff);
  58. }
  59. //打印读取的内容
  60. System.out.println("聊天信息:"+content);
  61. sk.interestOps(SelectionKey.OP_READ);
  62. }
  63. }
  64. }
  65. }catch(IOException io){
  66. io.printStackTrace();
  67. }
  68. }
  69. }
  70. public static void main(String [] args) throws IOException{
  71. new NClient().init();
  72. }
  73. }

java nio实现非阻塞Socket通信实例的更多相关文章

  1. JAVA基础知识之网络编程——-基于NIO的非阻塞Socket通信

    阻塞IO与非阻塞IO 通常情况下的Socket都是阻塞式的, 程序的输入输出都会让当前线程进入阻塞状态, 因此服务器需要为每一个客户端都创建一个线程. 从JAVA1.4开始引入了NIO API, NI ...

  2. Java NIO 同步非阻塞

    同步非阻塞IO (NIO) NIO是基于事件驱动思想的,实现上通常采用Reactor(http://en.wikipedia.org/wiki/Reactor_pattern)模式,从程序角度而言,当 ...

  3. JAVA NIO使用非阻塞模式实现高并发服务器

    参考:http://blog.csdn.net/zmx729618/article/details/51860699  https://zhuanlan.zhihu.com/p/23488863 ht ...

  4. 【转载】高性能IO设计 & Java NIO & 同步/异步 阻塞/非阻塞 Reactor/Proactor

    开始准备看Java NIO的,这篇文章:http://xly1981.iteye.com/blog/1735862 里面提到了这篇文章 http://xmuzyq.iteye.com/blog/783 ...

  5. java的高并发IO原理,阻塞BIO同步非阻塞NIO,异步非阻塞AIO

    原文地址: IO读写的基础原理 大家知道,用户程序进行IO的读写,依赖于底层的IO读写,基本上会用到底层的read&write两大系统调用.在不同的操作系统中,IO读写的系统调用的名称可能不完 ...

  6. Flex通信-与Java实现Socket通信实例

    Flex通信-与Java实现Socket通信实例  转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...

  7. Java Socket 通信实例 - 转载

    基于Tcp协议的简单Socket通信实例(JAVA)   好久没写博客了,前段时间忙于做项目,耽误了些时间,今天开始继续写起~ 今天来讲下关于Socket通信的简单应用,关于什么是Socket以及一些 ...

  8. java并发之非阻塞算法介绍

    在并发上下文中,非阻塞算法是一种允许线程在阻塞其他线程的情况下访问共享状态的算法.在绝大多数项目中,在算法中如果一个线程的挂起没有导致其它的线程挂起,我们就说这个算法是非阻塞的. 为了更好的理解阻塞算 ...

  9. 4.NIO的非阻塞式网络通信

    /*阻塞 和 非阻塞 是对于 网络通信而言的*/ /*原先IO通信在进行一些读写操作 或者 等待 客户机连接 这种,是阻塞的,必须要等到有数据被处理,当前线程才被释放*/ /*NIO 通信 是将这个阻 ...

随机推荐

  1. 平时有没有使用xml和json

    平时有没有使用xml和json,在ajax交互中,哪一种更易于开发和维护,js中怎么序列化JSON字符串? 有,json相比xml可读性和可扩张性好.编码及解码难度较低.在数据交互中带宽占用少,并且在 ...

  2. rfcn讲解博客

    http://www.cnblogs.com/lillylin/p/6277094.html ROI pooling操作的输入(对于C+1个类)是k^2*(C+1)*W' *H'(W'和H'是ROI的 ...

  3. Xgboost集成算法

    集成算法思想: Xgboost基本原理: Xboost中是一个树(函数)接着一个树(函数)往里加,每加一个树都希望整体表达效果更好一些,即:目标函数逐步减小. 每加入一个函数,使目标函数逐渐减小,整体 ...

  4. 普通用户切换到root用户

    普通用户切换到root用户首先按组合键 CTRL+ALT+T 进入终端界面,一般终端界面默认为普通用户权限模式,如何从普通用户进入root用户首先重置root密码输入 sudo passwd root ...

  5. SQL Server连接不上本地服务器

    昨天星期一,到公司,如常打开电脑后,上个厕所,吃个早餐,电脑才完全醒来.打开项目后台,发现登不上,用户名或密码错误,认真输入几遍,还是错误,打开本地数据库,sql server连接不上,提示错误: 我 ...

  6. 记录xerces使用(VS2017 C++)

    1.编译xerces,获得dll文件和lib文件 2.将dll文件和lib文件拷贝到使用xerces的工程目录里面去 3.配置VS2017 C/C++  ->  All Options --&g ...

  7. Oracle 10g R2 Transparent Data Encryption 透明数据加密

    Oracle 10g R2 Transparent Data Encryption 透明数据加密 本章介绍如何使用透明数据加密来保护Oracle数据库中的敏感数据,该功能使您可以加密数据库列并管理加密 ...

  8. kvm的4中网络模型(qemu-kvm)

    1. 隔离模式(类似vmare中仅主机模式):虚拟机之间组建网络,该模式无法与宿主机通信,无法与其他网络通信,相当于虚拟机只是连接到一台交换机上,所有的虚拟机能够相互通信. 2. 路由模式:相当于虚拟 ...

  9. tornado框架基础06-SQLAlchemy连接数据库

    01 ORM 在服务器后台,数据是要存储在数据库的,但是如果项目在开发和部署的时候,是使用的不同的数据库,该怎么办呢?是不是需要把所有的 SQL 语句都再重新写一遍呢? 和数据库相关,不同的数据库需要 ...

  10. day22 01 初识面向对象----简单的人狗大战小游戏

    day22 01 初识面向对象----简单的人狗大战小游戏 假设有一个简单的小游戏:人狗大战   怎样用代码去实现呢? 首先得有任何狗这两个角色,并且每个角色都有他们自己的一些属性,比如任务名字nam ...