我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么用nio实现Echo服务

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么用nio实现Echo服务

这篇文章主要介绍“怎么用nio实现Echo服务”,在日常操作中,相信很多人在怎么用nio实现Echo服务问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用nio实现Echo服务”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

今天突然间想用nio实现个Echo服务,程序实现起来实现不算困难,但跑起来后,在Server端的ServerSocket完成accept之后,我的CPU总是跳到100%。嗯,小郁闷,后来,才发现自己在Server端注册了多余的监听事件SelectionKey.OP_WRITE,改过来后好多了,希望记住这个教训。

EchoServer.java

package edu.dlut.zxf.nio;   import java.io.IOException;  import java.net.InetAddress;  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.Set;    public class EchoServer {      public final static int BUFFER_SIZE = 1024; //默认端口      public final static String HOST = "210.30.107.17";      public final static int PORT = 8888;            public static void main(String[] args) {          ServerSocketChannel ssc = null;          //缓冲区          ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);          Selector selector = null;          try {              selector = Selector.open();              ssc = ServerSocketChannel.open();              ssc.socket().bind(new InetSocketAddress(InetAddress.getByName(HOST), PORT));              ssc.configureBlocking(false);              ssc.register(selector, SelectionKey.OP_ACCEPT);                   print("服务器启动,准备好连接...");              while (selector.select() > 0) {                       Set<SelectionKey> selectionKeys = selector.selectedKeys();                  for (SelectionKey key: selectionKeys) {                      if (key.isAcceptable()) {                          SocketChannel sc = ssc.accept();                          print("有新的连接!地址:" + sc.socket().getRemoteSocketAddress());                          sc.configureBlocking(false);                          sc.register(selector, SelectionKey.OP_READ);                          // 不要写成:                          // sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);                          // 毕竟这样多注册的无用的事件SelectionKey.OP_WRTE                          // 如果是这样,在完成accept后,CPU也许会跑到100%                                                }                      //same to if ((ops & SelectionKey.OP_READ) == SelectionKey.OP_READ) {                      if (key.isReadable()) {                           SocketChannel sc = (SocketChannel)key.channel();                          print("有新的读取!地址:" + sc.socket().getRemoteSocketAddress());                                                buffer.clear();                                               sc.read(buffer);                          buffer.flip();                          byte[] b = new byte[buffer.limit()];                          buffer.get(b);                          String s = new String(b);                          if (s.equals("bye")) {                              print("断开连接:" + sc.socket().getRemoteSocketAddress());                                //断开连接后,取消此键的通道到其选择器的注册                              key.cancel();                              sc.close();                              continue;                          }                          print("读取的内容为:" + s);                             buffer.clear();                          s = "echo: " + s;                          buffer.put(s.getBytes());                          buffer.flip();                          sc.write(buffer);                      }                   }                  selectionKeys.clear();              }          } catch(IOException e) {              e.printStackTrace();          }       }            private static void print(String s) {          System.out.println(s);      }  }

EchoClient.java

package edu.dlut.zxf.nio;   import java.util.Set;  import java.io.BufferedReader;  import java.io.IOException;  import java.io.InputStreamReader;  import java.net.InetSocketAddress;  import java.net.InetAddress;  import java.nio.ByteBuffer;  import java.nio.channels.SelectionKey;  import java.nio.channels.Selector;  import java.nio.channels.SocketChannel;    public class EchoClient {      public static void main(String[] args) {          ByteBuffer buffer = ByteBuffer.allocate(EchoServer.BUFFER_SIZE);          Selector selector = null;          SocketChannel sc = null;          try {              selector = Selector.open();              sc = SocketChannel.open();              sc.configureBlocking(false);              sc.connect(new InetSocketAddress(InetAddress.getByName(EchoServer.HOST), EchoServer.PORT));              print("客户端启动,准备连接...");              if (sc.isConnectionPending()) {                  sc.finishConnect();              }              print("完成连接");              sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);                            boolean writed = false;              boolean down = false;              while (!down && selector.select() > 0) {                                  Set<SelectionKey> selectionKeys = selector.selectedKeys();                  for (SelectionKey key: selectionKeys) {                                       //int ops = key.readyOps();                      //if ((ops & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE && !writed) {                      if (key.isWritable() && !writed) {                          System.out.print("Input(bye to end): ");                          BufferedReader br = new BufferedReader(new InputStreamReader(System.in));                           String s = br.readLine();                          if (s != null && !s.trim().equals("")) {                              buffer.clear();                              buffer.put(s.getBytes());                              buffer.flip();                              sc.write(buffer);                              writed = true;                              if (s.equals("bye")) {                                  down = true;                                  break;                              }                          }                      }                      //if ((ops & SelectionKey.OP_READ) == SelectionKey.OP_READ && writed) {                      if (key.isReadable() && writed) {                          buffer.clear();                          sc.read(buffer);                          buffer.flip();                          byte[] b = new byte[buffer.limit()];                          buffer.get(b);                          print(new String(b));                          writed = false;                      }                  }                  selectionKeys.clear();              }          } catch(IOException e) {              e.printStackTrace();          }      }            private static void print(String s) {          System.out.println(s);      }  }

当然EchoClient也可以像下面这样来实现:

EchoClient2.java

package edu.dlut.zxf.nio;   import java.util.Set;  import java.io.BufferedReader;  import java.io.IOException;  import java.io.InputStreamReader;  import java.net.InetSocketAddress;  import java.net.InetAddress;  import java.nio.ByteBuffer;  import java.nio.channels.SelectionKey;  import java.nio.channels.Selector;  import java.nio.channels.SocketChannel;    public class EchoClient2 {      public static void main(String[] args) {          ByteBuffer buffer = ByteBuffer.allocate(EchoServer.BUFFER_SIZE);          Selector selector = null;          SocketChannel sc = null;          try {              selector = Selector.open();              sc = SocketChannel.open();              sc.configureBlocking(false);              sc.register(selector, SelectionKey.OP_CONNECT);              sc.connect(new InetSocketAddress(InetAddress.getByName(EchoServer.HOST), EchoServer.PORT));              print("客户端启动,准备连接...");                            boolean writed = false;              boolean down = false;              while (!down && selector.select() > 0) {                                  Set<SelectionKey> selectionKeys = selector.selectedKeys();                  for (SelectionKey key: selectionKeys) {                                       //int ops = key.readyOps();                      //if ((ops & SelectionKey.OP_CONNECT) == SelectionKey.OP_CONNECT) {                      if (key.isConnectable()) {                          print("完成连接!");                          if (sc.isConnectionPending()) {                              sc.finishConnect();                          }                          sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);                                      }                      //if ((ops & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE && !writed) {                      if (key.isWritable() && !writed) {                          //从准备IO中读取内容                          System.out.print("Input(bye to end): ");                          BufferedReader br = new BufferedReader(new InputStreamReader(System.in));                           String s = br.readLine();                          if (s != null && !s.trim().equals("")) {                              buffer.clear();                              buffer.put(s.getBytes());                              buffer.flip();                              sc.write(buffer);                              writed = true;                              if (s.equals("bye")) {                                  down = true;                                  break;                              }                          }                      }                      //if ((ops & SelectionKey.OP_READ) == SelectionKey.OP_READ && writed) {                      if (key.isReadable() && writed) {                          buffer.clear();                          sc.read(buffer);                          buffer.flip();                          byte[] b = new byte[buffer.limit()];                          buffer.get(b);                          print(new String(b));                          writed = false;                      }                  }                  selectionKeys.clear();              }          } catch(IOException e) {              e.printStackTrace();          }      }            private static void print(String s) {          System.out.println(s);      }  }

但是这样的话,显然EchoClient2中的while循环中的for循环(若有n次),在每次循环中都会多出n-1次if判断,就是下面这个:

if (key.isConnectable()) {

到此,关于“怎么用nio实现Echo服务”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

怎么用nio实现Echo服务

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

怎么用nio实现Echo服务

这篇文章主要介绍“怎么用nio实现Echo服务”,在日常操作中,相信很多人在怎么用nio实现Echo服务问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用nio实现Echo服务”的疑惑有所帮助!接下来,请跟
2023-06-17

Java怎么实现NIO聊天室

这篇文章给大家分享的是有关Java怎么实现NIO聊天室的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。功能介绍功能:群聊+私发+上线提醒+下线提醒+查询在线用户文件Utils需要用maven导入下面两个包
2023-06-15

怎么使用Java NIO实现多人聊天室

本篇内容主要讲解“怎么使用Java NIO实现多人聊天室”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用Java NIO实现多人聊天室”吧!NIO服务端public class NioSe
2023-06-21

Java NIO就绪模式怎么实现

这篇文章主要介绍“Java NIO就绪模式怎么实现”,在日常操作中,相信很多人在Java NIO就绪模式怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java NIO就绪模式怎么实现”的疑惑有所帮助!
2023-06-17

如何在Golang中使用echo服务器实现socket.io服务器

问题内容我想初始化回显服务器app := echo.New()app.POST("/register", handlers.Register)app.Start(":5000")然后在同一端口实现socket.io服务器。我尝试
如何在Golang中使用echo服务器实现socket.io服务器
2024-02-05

Java中怎么使用NIO实现网络编程

本篇文章为大家展示了Java中怎么使用NIO实现网络编程,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。为什么需要NIO使用Java编写过Socket程序的同学一定都知道Socket和SocketSe
2023-06-17

Java NIO怎么实现聊天室功能

这篇文章主要介绍了Java NIO怎么实现聊天室功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体内容如下代码里面已经包含了必要的注释,这里不详述了。实现了基本的聊天室功
2023-06-21

基于Java NIO的即时聊天服务器模型怎么实现

这篇文章主要讲解了“基于Java NIO的即时聊天服务器模型怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“基于Java NIO的即时聊天服务器模型怎么实现”吧!废话不多说,关于NIO
2023-06-17

Java NIO怎么实现聊天室程序

本文小编为大家详细介绍“Java NIO怎么实现聊天室程序”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java NIO怎么实现聊天室程序”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。服务端:package t
2023-06-17

java NIO怎么实现简单聊天程序

这篇文章主要为大家展示了“java NIO怎么实现简单聊天程序”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“java NIO怎么实现简单聊天程序”这篇文章吧。具体内容如下服务端功能:1、接受客户
2023-06-21

Java基于NIO怎么实现聊天室功能

Java基于NIO怎么实现聊天室功能,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Sever端package com.qst.one;import java.io.IOExce
2023-06-21

基于.NET 7 的 QUIC 实现 Echo 服务的详细过程

这篇文章主要介绍了基于.NET 7 的 QUIC实现Echo服务,下面的内容中,我会介绍如何在.NET 中使用 Quic,文中结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2022-11-13

云服务器怎么实现高可用

要实现云服务器的高可用性,可以采取以下措施:1. 使用负载均衡:将流量均匀地分发到多台服务器上,避免单点故障,提高系统的可用性。2. 配置冗余系统:通过使用冗余服务器,当一台服务器出现故障时,可以自动切换到备用服务器上,保证服务的连续性。3
2023-09-22

云服务器怎么实现高可用

云服务器高可用性实现高可用性对云服务器至关重要,可确保在故障下不间断服务。本文探索实现高可用性的方法:备份和恢复:定期备份数据,利用快照功能快速恢复。冗余架构:使用负载均衡器和故障转移机制创建服务器副本。自动化和监控:利用工具检测故障并触发恢复,持续监视服务器性能。云服务提供商功能:选择支持高可用性的提供商,利用可用性区域和管理工具。分层方法、灾难恢复演练和持续更新可提高高可用性。通过这些措施,企业可以降低故障影响,确保服务不间断交付。
云服务器怎么实现高可用
2024-04-11

怎么用C#实现WINDOWS服务程序

这篇文章主要讲解了“怎么用C#实现WINDOWS服务程序”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么用C#实现WINDOWS服务程序”吧!在做C# WINDOWS服务之前先熟悉一下C#
2023-06-17

怎么用C#实现Windows后台服务

这篇文章主要讲解了“怎么用C#实现Windows后台服务”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么用C#实现Windows后台服务”吧!C#实现Windows后台服务实例之前要明白的
2023-06-17

Qt怎么实现http服务

本篇内容介绍了“Qt怎么实现http服务”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!先看执行结果:Qt HttpServer左边是开启的Q
2023-07-06

golang微服务怎么实现

Go语言的微服务可以通过以下步骤来实现:设计服务接口:确定微服务的功能和接口,定义服务的输入输出参数。创建服务模块:使用Go语言编写服务模块,将服务的功能封装在一个独立的模块中。这个模块可以是一个独立的包,也可以是一个独立的项目。定义服务路
2023-10-23

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录