netty学习十一:NIO客户端服务端通讯demo
来源:互联网 发布:大数据分析的案例 编辑:程序博客网 时间:2024/05/24 01:55
概述
本文展示了如何使用NIO来进行客户端和服务端的通讯.
服务端代码
package nio;import java.io.IOException;import java.net.InetSocketAddress;import java.net.ServerSocket;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.nio.charset.Charset;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Set;import java.util.UUID;public class NioServer { private static Map<String,SocketChannel> clientMap = new HashMap<>(); public static void main(String[] args) throws IOException { //创建一个服务端的socket channel,但是还未绑定监听地址 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); //非阻塞 serverSocketChannel.configureBlocking(false); ServerSocket serverSocket = serverSocketChannel.socket(); //通过ServerSocet为ServerSocketChannel指定监听地址 //如果不绑定的话,调用ServerSocketChannel的accept方法会抛出NotYetBoundException serverSocket.bind(new InetSocketAddress(8899)); Selector selector = Selector.open(); //注册连接建立的事件 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (true) { //一直阻塞,直到有感兴趣的事件发生,select方法才会返回 selector.select(); //注册selector在上的事件可能不止一个,这些事件也可能同时发生,所以这里是SelectionKey Set集合 Set<SelectionKey> selectedKeys = selector.selectedKeys(); for (Iterator<SelectionKey> iterator = selectedKeys.iterator(); iterator.hasNext();) { SelectionKey selectionKey = (SelectionKey) iterator.next(); final SocketChannel client; //isAcceptable==true,说明客户端和服务端已经建立好连接了 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); continue; } //isReadable==true,说明可以从SocketChannel中读取数据了 if(selectionKey.isReadable()) { client = (SocketChannel)selectionKey.channel(); ByteBuffer readBuffer = ByteBuffer.allocate(1024); //从channel中读取数据 int count = client.read(readBuffer); if(count > 0) { readBuffer.flip(); Charset charset = Charset.forName("utf-8"); //将bytebuffer转换成字符串 String receiveMessage = String.valueOf(charset.decode(readBuffer).array()); System.out.println(client+":"+receiveMessage); //找出发送消息的客户端 String sendKey = ""; for (String key : clientMap.keySet()) { SocketChannel socketChannel = clientMap.get(key); if (socketChannel == client) { sendKey = key; break; } } for (String key : clientMap.keySet()) { SocketChannel socketChannel = clientMap.get(key); ByteBuffer writeBuffer = ByteBuffer.allocate(1024); writeBuffer.put((sendKey + ":" +receiveMessage).getBytes()); writeBuffer.flip(); socketChannel.write(writeBuffer); } } } } //清除事件 selectedKeys.clear(); } }}
客户端代码
package nio;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.time.LocalDateTime;import java.util.Set;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class NioClient { public static void main(String[] args) throws IOException { SocketChannel socketChannel = SocketChannel.open(); //非阻塞 socketChannel.configureBlocking(false); //客户端同样需要selector去监听channel 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> selectedKeys = selector.selectedKeys(); for (SelectionKey selectionKey : selectedKeys) { //isConnectable=true,说明已经跟服务端建立连接了 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(new Runnable() { @Override public void run() { while(true) { writeBuffer.clear(); InputStreamReader inputStreamReader = new InputStreamReader(System.in); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); try { String sendMessage = bufferedReader.readLine(); writeBuffer.put(sendMessage.getBytes()); writeBuffer.flip(); client.write(writeBuffer); } catch (IOException e) { e.printStackTrace(); } } } }); } //一旦客户端和服务端建立连接了,立刻注册读事件 client.register(selector, SelectionKey.OP_READ); continue; } if(selectionKey.isReadable()) { SocketChannel client = (SocketChannel)selectionKey.channel(); ByteBuffer readBuffer = ByteBuffer.allocate(1024); int count = client.read(readBuffer); if (count > 0) { String receiveMessage = new String(readBuffer.array(),0,count); System.out.println(receiveMessage); } } } //清除事件 selectedKeys.clear(); } }}
csdn code 路径
这个项目的源代码放置在csdn code上,欢迎访问。
netty_study
阅读全文
3 0
- netty学习十一:NIO客户端服务端通讯demo
- 2、NIO客户端和服务端示例代码(netty学习笔记)
- Netty初探-netty服务端和客户端demo
- Netty初探-netty服务端和客户端demo
- NIO 客户端与服务端通信demo
- Netty实现服务端客户端长连接通讯及心跳检测
- Netty实现服务端客户端长连接通讯及心跳检测
- Netty实现服务端客户端长连接通讯及心跳检测
- netty学习二:基于socket通讯的小demo
- netty入门学习(3)-客户端写消息,服务端应答
- Netty学习5-Netty3.X服务端与客户端
- Netty学习 netty nio编程
- 通过netty实现服务端与客户端的长连接通讯,及心跳检测。
- Netty实现服务端客户端长连接通讯、心跳检测及自定义报文发送(一)
- tcp客户端服务端demo
- Dubbo服务端/客户端demo
- netty 简单服务端和客户端
- 17.5.3第一天—netty实现服务端与客户端的通讯,并且获取服务端的cpu,内存等性能
- bzoj 1607: [Usaco2008 Dec]Patting Heads 轻拍牛头
- C++获取磁盘分区空间情况
- Java 数组的不同定义方式和数组长度为可变参数
- Java四种线程池的使用
- 树状数组
- netty学习十一:NIO客户端服务端通讯demo
- hdu-3018-Ant Trip(并查集&&欧拉回路)
- 旅程
- jqGrid API 及用法
- vmware fusion在centos7中配置静态ip
- iOS编译过程的原理和应用
- 通过jQuery Ajax使用FormData对象上传文件
- python入门(十七):sys模块
- A. Greg's Workout CodeForces255A