1、创建服务端代码

public class NioServer {

    private static Map<String, SocketChannel> clientMap = new HashMap<>();

    public static void main(String[] args) throws IOException {

        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
ServerSocket serverSocket = serverSocketChannel.socket();
serverSocket.bind(new InetSocketAddress(8899)); Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (true){
try {
selector.select();
Set<SelectionKey> selectionKeys = selector.selectedKeys();
selectionKeys.forEach( selectionKey -> { final SocketChannel client;
try{
//客户端向服务端发起一个连接
if(selectionKey.isAcceptable()){
ServerSocketChannel server = (ServerSocketChannel)selectionKey.channel();
client = server.accept();
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ);
String key = "[" + UUID.randomUUID() + "]";
clientMap.put(key, client); }
//有数据可读
else if(selectionKey.isReadable()){
client = (SocketChannel)selectionKey.channel();
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
int count = client.read(readBuffer);
if(count > 0){
readBuffer.flip(); Charset charset = Charset.forName("utf-8"); String receivedMessage = String.valueOf(charset.decode(readBuffer).array()); System.out.println(client + ": " + receivedMessage); String senderKey = null; for(Map.Entry<String,SocketChannel> entry : clientMap.entrySet()){
if(client == entry.getValue()){
senderKey = entry.getKey();
break;
}
} for(Map.Entry<String,SocketChannel> entry : clientMap.entrySet()){
SocketChannel value = entry.getValue();
ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
writeBuffer.put((senderKey + ":" + receivedMessage).getBytes());
writeBuffer.flip();
value.write(writeBuffer);
} }
}
}catch (Exception ex){
ex.printStackTrace();
}
}); selectionKeys.clear(); }catch (Exception ex){
ex.printStackTrace();
}
} }
}

  

2、创建客户端代码

public class NioClient {

    public static void main(String[] args) {
try{ SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false); Selector selector = Selector.open();
socketChannel.register(selector, SelectionKey.OP_CONNECT); socketChannel.connect(new InetSocketAddress("127.0.0.1",8899)); while (true){
selector.select();
Set<SelectionKey> keySet = selector.selectedKeys(); for(SelectionKey selectionKey : keySet){
//与服务端已经建立好了连接
if(selectionKey.isConnectable()){
SocketChannel client = (SocketChannel)selectionKey.channel();
if(client.isConnectionPending()){
client.finishConnect();
//向服务端发数据
ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
writeBuffer.put((LocalDateTime.now() + "连接成功").getBytes());
writeBuffer.flip();
client.write(writeBuffer); // 启动一个线程,不断的读取标准输入的内容。然后将内容向回个服务端
ExecutorService executorService = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
executorService.submit(() -> {
while (true){ try {
writeBuffer.clear();
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(input); String sendMessage = br.readLine(); writeBuffer.put(sendMessage.getBytes());
writeBuffer.flip();
client.write(writeBuffer); }catch (Exception ex){ ex.printStackTrace();
}
}
}); }
client.register(selector, SelectionKey.OP_READ);
}else if(selectionKey.isReadable()){
SocketChannel client = (SocketChannel)selectionKey.channel();
ByteBuffer readBuffer = ByteBuffer.allocate(1024); int count = client.read(readBuffer); if(count > 0){
String receivedMessage = new String(readBuffer.array(), 0, count);
System.out.println(receivedMessage);
} }
}
keySet.clear();
} }catch (Exception ex){
ex.printStackTrace();
}
}
}

  

3、测试

1) 启动服务端

2) 启动两个客户端

3) 输出结果

NioServer输出

第一个NioClient输出。连接建立后,输入hello

第二个NioClient输出。 连接建立后,输入world

NIO网络编程的更多相关文章

  1. Netty | 第1章 Java NIO 网络编程《Netty In Action》

    目录 前言 1. Java 网络编程 1.1 Javs NIO 基本介绍 1.2 缓冲区 Buffer 1.2 通道 Channel 1.3 选择器 Selector 1.4 NIO 非阻塞网络编程原 ...

  2. java 基础之--nio 网络编程

    在传统的Java 网络编程中,对于客户端的每次连接,对于服务器来说,都要创建一个新的线程与客户端进行通讯,这种频繁的线程的创建,对于服务器来说,是一种巨大的损耗,在Java 1.4 引入Java ni ...

  3. Netty学习(4):NIO网络编程

    概述 在 Netty学习(3)中,我们已经学习了 Buffer 和 Channel 的概念, 接下来就让我们通过实现一个 NIO 的多人聊天服务器来深入理解 NIO 的第 3个组件:Selector. ...

  4. Java NIO网络编程demo

    使用Java NIO进行网络编程,看下服务端的例子 import java.io.IOException; import java.net.InetAddress; import java.net.I ...

  5. 【Netty】netty学习之nio网络编程的模型

    [一]NIO服务器编程结构 [二]Netty3.x服务端线程模型

  6. Java NIO 网络编程基础

    Java NIO提供了一套网络api,可以用来处理连接数很多的情况.他的基本思想就是用一个线程来处理多个channel. 123456789101112131415161718192021222324 ...

  7. NIO网络编程中重复触发读(写)事件

    一.前言 公司最近要基于Netty构建一个TCP通讯框架, 因Netty是基于NIO的,为了更好的学习和使用Netty,特意去翻了之前记录的NIO的资料,以及重新实现了一遍NIO的网络通讯,不试不知道 ...

  8. java基础-网络编程(Socket)技术选型入门之NIO技术

    java基础-网络编程(Socket)技术选型入门之NIO技术 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传统的网络编程 1>.编写socket通信的MyServer ...

  9. Java网络编程 -- NIO非阻塞网络编程

    从Java1.4开始,为了替代Java IO和网络相关的API,提高程序的运行速度,Java提供了新的IO操作非阻塞的API即Java NIO.NIO中有三大核心组件:Buffer(缓冲区),Chan ...

随机推荐

  1. HTML 初始

    HTML(Hyper Text Markup Language的缩写)中文译为“超文本标记语言”,主要是通过HTML标签对网页中的文本.图片.声音等内容进行描述. 一.HTML 骨架结构 每种语言都有 ...

  2. OpenFire后台插件上传获取webshell及免密码登录linux服务器

    1.目标获取 (1)fofa.so网站使用搜索body="Openfire, 版本: " && country=JP,可以获取日本存在的Openfire服务器.如图 ...

  3. 安卓样式Style和主题Theme

    1. 区别 不过style是针对view来说的,比如TextView和EditText这些:而Theme必须针对整个activity或者整个application 2. 样式 创建一个样式,根元素 & ...

  4. 排序算法的c++实现——插入排序

    插入排序的思想是:给定一个待排序的数组,我们从中选择第一个元素作为有序的基态(单个元素肯定是有序的), 然后从剩余的元素中选择一个插入到有序的基态中,使插入之后的序列也是有序状态,重复此过程,直到全部 ...

  5. JS 基本操作

    1.判断数据是否包含某些数据 var ary=[{age:20,name:"a"},{age:20,name:"b"},,{age:30,name:" ...

  6. 第十周LINUX 学习笔记

    LVS集群nat丶DR HA:高可用    平均无故障时间/(平均无故障时间+平均修复时间)        负载均衡 次序lb(负载)——>ha()LB  tcp:lvs,haproxy  应用 ...

  7. 调用python脚本报错/usr/bin/env: python : No such file or directory

    一.调用python脚本报错 /usr/bin/env: python: No such file or directory 二.解决方法 原因是在windows上编写的脚本,使用dos2unix对脚 ...

  8. Fire Balls 03—— 多个圆环以及圆环的变速变向

    版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...

  9. 使用Python音频双通道分离

    某些音频是双方对话,有可能需要对音频作通道的分离. 示例代码如下: #!/usr/bin/env python # -*- coding: utf-8 -*- """ 音 ...

  10. input事件在进行模糊搜索时,用到的即时监测input的值变化的方法(即时搜索的input和propertychange方法)

    做搜索功能的时候,经常遇到输入框检查的需求,最常见的是即时搜索,今天好好小结一下. 即时搜索的方案: (1)change事件    触发事件必须满足两个条件: a)当前对象属性改变,并且是由键盘或鼠标 ...