您好,欢迎来到教培网!请登录免费注册选课学习指南
广州
教培网
外语/小语种电脑/IT/设计职业技能学历教育
广州拓胜科技轮播1广州拓胜科技轮播2广州拓胜科技轮播3广州拓胜科技轮播4广州拓胜科技轮播5
学校环境校区与课堂实景
查看学校相册

广州拓胜科技

V2
4.71人评价
Java5门课程1个校区31人预约
正规学校助学补贴优质服务多校区资质认证
校区
广州大学城校区
地址
广州番禺大学城广中医13栋数字家庭5楼
电话
18347319277
简介
拓胜(广州)计算机技术服务有限公司是中国浸入式IT职业教育与人才服务的,公司总部座落在环境优美、人文气息浓厚的广州数字家庭孵化基地,坐拥5星级的培训基地,与数百 详情
当前位置:教培网>广州拓胜科技>学校动态>Java NIO编程应用示例

Java NIO编程应用示例

作者:教培网来源:教培网地区:广州

NIO是Java提供的非阻塞I/O API。非阻塞的意义在于可以使用一个线程对大量的数据连接进行处理,非常适用于"短数据长连接"的应用场景,例如即时通讯软件。在一个阻塞C/S系统中,服务器要为每一个客户连接开启一个线程阻塞等待客户端发送的消息。若使用非阻塞技术,服务器可以使用一个线程对连接进 行轮询,无须阻塞等待。这大大减少了内存资源的浪费,也避免了服务器在客户线程中不断切换带来的CPU消耗,服务器对CPU的有效使用率大大提高。其核心概念包括Channel,Selector,SelectionKey,Buffer。Channel是I/O通道,可以向其注册Selector,应用成功可以通过select操作获取当前通道已经准备好的可以无阻塞执行的操作。这由SelectionKey表示。

SelectionKey的常量字段SelectionKey.OP_***分别对应Channel的几种操作例如connect(),accept(),read(),write()。select操作后得到SelectionKey.OP_WRITE或者READ即可在Channel上面无阻塞调用read和write方 法,Channel的读写操作均需要通过Buffer进行。即读是讲数据从通道中读入Buffer然后做进一步处理。写需要先将数据写入Buffer然后 通道接收Buffer。下面是一个使用NIO的基本C/S示例。该示例只为显示如何使用基本的API而存在,其代码的健壮性,合理性都不具参考价值。这个示例,实现一个简单的C/S,客户端想服务器端发送消息,服务器将收到的消息打印到控制台。

现实的应用中需要定义发送数据使用的协议,以帮 助服务器解析消息。本示例只是无差别的使用默认编码将收到的字节转换字符并打印。通过改变初始分配的ByteBuffer的容量,可以看到打印消息的变 化。容量越小,对一条消息的处理次数就越多,容量大就可以在更少的循环次数内读完整个消息。所以真是的应用场景,要考虑适当的缓存大小以提高效率。

首先是Server: 1. package hadix.demo.nio; 2. 3. import java.io.IOException; 4. import java.net.InetSocketAddress; 5. import java.nio.ByteBuffer; 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.util.*; 11. import java.util.concurrent.ConcurrentHashMap; 12. 13. /** 14. * User: hAdIx 15. * Date: 11-11-2 16. * Time: 上午11:26 17. */ 18. public class Server { 19. private Selector selector; 20. private ByteBuffer readBuffer = ByteBuffer.allocate(8);

//调整缓存的大小可以看到打印输出的变化 21. private Map clientMessage = new ConcurrentHashMap<>();22. 23. public void start() throws IOException { 24. ServerSocketChannel ssc = ServerSocketChannel.open();25. ssc.configureBlocking(false);26. ssc.bind(new InetSocketAddress("localhost", 8001));27. selector = Selector.open();28. ssc.register(selector, SelectionKey.OP_ACCEPT);

29. while (!Thread.currentThread()。isInterrupted()) { 30. selector.select();31. Setkeys = selector.selectedKeys();32. IteratorkeyIterator = keys.iterator();33. while (keyIterator.hasNext()) { 34. SelectionKey key = keyIterator.next();35. if (!key.isValid()) { 36. continue; 37. } 38. if (key.isAcceptable()) { 39. accept(key);

40. } else if (key.isReadable()) { 41. read(key);42. } 43. keyIterator.remove();44. } 45. } 46. } 47. 48. private void read(SelectionKey key) throws IOException { 49. SocketChannel socketChannel = (SocketChannel) key.channel();50. 51. // Clear out our read buffer so it's ready for new data 52. this.readBuffer.clear();

53. 54. // Attempt to read off the channel 55. int numRead; 56. try { 57. numRead = socketChannel.read(this.readBuffer);58. } catch (IOException e) { 59. // The remote forcibly closed the connection, cancel 60. // the selection key and close the channel. 61. key.cancel();62. socketChannel.close();63. clientMessage.remove(socketChannel);

64. return; 65. } 66. 67. byte[] bytes = clientMessage.get(socketChannel);68. if (bytes == null) { 69. bytes = new byte[0]; 70. } 71. if (numRead > 0) { 72. byte[] newBytes = new byte[bytes.length + numRead]; 73. System.arraycopy(bytes, 0, newBytes, 0, bytes.length);74. System.arraycopy(readBuffer.array(), 0, newBytes, bytes.length, numRead);

75. clientMessage.put(socketChannel, newBytes);76. System.out.println(new String(newBytes));77. } else { 78. String message = new String(bytes);79. System.out.println(message);80. } 81. } 82. 83. private void accept(SelectionKey key) throws IOException { 84. ServerSocketChannel ssc = (ServerSocketChannel) key.channel();

85. SocketChannel clientChannel = ssc.accept();86. clientChannel.configureBlocking(false);87. clientChannel.register(selector, SelectionKey.OP_READ);88. System.out.println("a new client connected");89. } 90. 91. 92. public static void main(String[] args) throws IOException { 93. System.out.println("server started…");94. new Server()。start();

95. } 96. } 然后是Client: 1. package hadix.demo.nio; 2. 3. import java.io.IOException; 4. import java.net.InetSocketAddress; 5. import java.nio.ByteBuffer; 6. import java.nio.channels.SelectionKey; 7. import java.nio.channels.Selector; 8. import java.nio.channels.SocketChannel; 9. import java.util.Iterator; 10. import java.util.Scanner; 11. import java.util.Set; 12. 13. /** 14. * User: hAdIx 15. * Date: 11-11-2 16. * Time: 上午11:26 17. */ 18. public class Client { 19. 20. public void start() throws IOException { 21. SocketChannel sc = SocketChannel.open();

22. sc.configureBlocking(false);23. sc.connect(new InetSocketAddress("localhost", 8001));24. Selector selector = Selector.open();25. sc.register(selector, SelectionKey.OP_CONNECT);26. Scanner scanner = new Scanner(System.in);27. while (true) { 28. selector.select();29. Setkeys = selector.selectedKeys();30. System.out.println("keys=" + keys.size());

31. IteratorkeyIterator = keys.iterator();32. while (keyIterator.hasNext()) { 33. SelectionKey key = keyIterator.next();34. keyIterator.remove();35. if (key.isConnectable()) { 36. sc.finishConnect();37. sc.register(selector, SelectionKey.OP_WRITE);38. System.out.println("server connected…");

39. break; 40. } else if (key.isWritable()) { 41. 42. System.out.println("please input message");43. String message = scanner.nextLine();44. ByteBuffer writeBuffer = ByteBuffer.wrap(message.getBytes());45. sc.write(writeBuffer);46. } 47. } 48. } 49. } 50. 51. public static void main(String[] args) throws IOException { 52. new Client()。start();53. } 54. }

分享到:

相关课程

官方授权声明

尊敬的平台会员您好,[广州拓胜科技]资料由平台整理展示,资质、课程、校区、图片和文案均可在后台维护。如需了解[广州拓胜科技]服务明细或申请试听服务,请点击。

公开资料整理 | 待机构认领确认