NIO框架(4)---聊天室
2016-05-17 14:53
246 查看
前几篇文章介绍了NIO的几个主要构件,包括缓冲区Buffer、传输通道Channel、消息选择器Selector以及消息类别SelectionKey,接下来我们通过一个聊天室的例子来了解一下以上各种组件的用法。聊天室分为服务器端和客户端,服务器端接收客户端发来的请求消息,并生成一个Channel来处理客户端的消息;客户端生成Channel来连接服务器,发送消息,然后再注册一个新的Channel来接收服务器端发来的消息。
2.处理客户端发来的消息
3.生成新的Channel处理客户端发来的消息
4.将客户端消息广播到其他客户端
到此服务器端的功能基本完成
2.创建一个Channel来接收服务端发来的消息
3.处理服务器发来的消息
以上就完成了客户端基本功能。
具体代码请点击下载。
服务器
1.首先生成一个ServerSocketChannel,绑定地址,然后将它注册到一个打开的选择器上来接收客户端的连接:Selector selector = Selector.open(); ServerSocketChannel channel; channel = ServerSocketChannel.open(); channel.bind(new InetSocketAddress("127.0.0.1", 9999)); channel.configureBlocking(false); channel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("Server is running!"); while (true) { int readyChannels = selector.select(); if (readyChannels == 0) continue; Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> keyIterator = selectedKeys.iterator(); while (keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); keyIterator.remove(); dealConnection(selector, key); } }
2.处理客户端发来的消息
/** * 处理连接消息 * @param selector * @param key * @throws IOException * @throws Exception */ public void dealConnection(Selector selector, SelectionKey key) throws IOException, Exception { if(key.isAcceptable()) { //生成新的Channel来接收客户端发来的消息 registerChannel(selector, key); } if (key.isConnectable()) { System.out.println("a connection was established!"); } else if (key.isReadable()) { readDataFromSocket(key); } else if (key.isWritable()) { System.out.println("a channel was writing for data!"); readDataFromSocket(key); } }
3.生成新的Channel处理客户端发来的消息
/** * 服务器端注册channel * @param selector * @param key * @throws IOException * @throws ClosedChannelException */ public void registerChannel(Selector selector, SelectionKey key) throws IOException, ClosedChannelException { ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel sc = server.accept(); if (sc == null) { return; } sc.configureBlocking(false); sc.register(selector, SelectionKey.OP_READ); key.interestOps(SelectionKey.OP_ACCEPT); System.out.println("Server is listening from client :" + sc.getRemoteAddress()); sc.write(charset.encode("请输入姓名")); }
4.将客户端消息广播到其他客户端
/** * 广播消息 * @param selector * @param srcChannel * @param content * @throws IOException */ public void broadCast(Selector selector, SocketChannel srcChannel, String content) throws IOException { for(SelectionKey key : selector.keys()) { Channel targetchannel = key.channel(); if(targetchannel instanceof SocketChannel && targetchannel!=srcChannel) { SocketChannel dest = (SocketChannel)targetchannel; if(dest.isConnected()) dest.write(charset.encode(content)); } } }
到此服务器端的功能基本完成
客户端
1.注册Channel连接服务端sc = SocketChannel.open(); selector = Selector.open(); sc.connect(new InetSocketAddress("127.0.0.1", 9999)); sc.configureBlocking(false); sc.register(selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ);
2.创建一个Channel来接收服务端发来的消息
new Thread(new Runnable() { @Override public void run() { try { while(isRun) { int readyChannels = selector.select(); if(readyChannels == 0) continue; Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> keyIterator = selectedKeys.iterator(); while(keyIterator.hasNext()) { SelectionKey sk = (SelectionKey) keyIterator.next(); keyIterator.remove(); dealMsg(sk); } } } catch (IOException io) {} } }).start();
3.处理服务器发来的消息
/** * 处理服务器发来的消息 * @param sk * @throws IOException */ private void dealMsg(SelectionKey sk) throws IOException { if(sk.isReadable()) { String msg = uitl.readDataFromChannel((SocketChannel)sk.channel()); System.out.println(msg); sk.interestOps(SelectionKey.OP_READ); } }
以上就完成了客户端基本功能。
具体代码请点击下载。
相关文章推荐
- 小心服务器内存居高不下的元凶--WebAPI服务
- Android之使用Http协议实现文件上传功能
- 运维入门
- spymemcached源码中Reactor模式分析
- [原创]java局域网聊天系统
- Java IO与NIO的一些文件拷贝测试
- 利用开源软件打造自己的全功能远程工具
- Linux5.9无人值守安装
- 数据中心和云未来的十二大趋势
- 用vsftp快速搭建ftp服务器
- Linux快速构建apache web服务器
- 服务器监控策略浅谈
- 如何降低服务器采购成本 原理分析
- 建议的服务器分区办法
- 服务器托管六大优势分析
- Erlang实现的一个Web服务器代码实例
- 服务器技术全面解析
- 网马生成器 MS Internet Explorer XML Parsing Buffer Overflow Exploit (vista) 0day
- 保护DNS服务器的几点方法小结