- 浏览: 190940 次
- 性别:
- 来自: 苏州
文章分类
最新评论
-
wanglijunjsj:
谢谢,很有用
java log4j的一些总结 -
lxb_champagne:
this.init(); 类都没初始化好,this没用的。
java final变量的初始化问题 -
lg_asus:
上面代码有点小问题,最新代码:
public class Pr ...
判断素数 -
lg_asus:
测试10 million的以内的数据,算出所有素数时间在500 ...
判断素数 -
lg_asus:
文章中说错了:如果只是找一个数在不在其中,则可以直接遍历一次, ...
40亿不重复的正整数,如何判断一个数是否在其中
推荐参考:
http://rox-xmlrpc.sourceforge.net/niotut/index.html
下面是我写的一个小demo:
http://rox-xmlrpc.sourceforge.net/niotut/index.html
下面是我写的一个小demo:
import java.io.IOException; 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.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.text.MessageFormat; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * @author chega * * 2012-12-3下午6:41:21 * * 为每个客户端分配一个线程来执行,执行完后客户端连接并不关闭(即长连接) */ public class MyServer { Selector selector; Map<SocketChannel, StringBuilder> channelMap; CharsetDecoder decoder = Charset.forName("utf-8").newDecoder(); ExecutorService executors = Executors.newCachedThreadPool(); private MessageFormat format = new MessageFormat("{0, time, medium}, {1}"); public static void main(String... args) { try { new MyServer().init(); } catch (IOException e) { e.printStackTrace(); } } private void init() throws IOException { this.channelMap = Collections.synchronizedMap(new HashMap<SocketChannel, StringBuilder>()); selector = Selector.open(); ServerSocketChannel channel = ServerSocketChannel.open(); channel.configureBlocking(false); channel.socket().bind(new InetSocketAddress("localhost", 80)); print("ServerSocket绑定在本机80端口,等待客户端连接"); channel.register(selector, SelectionKey.OP_ACCEPT); while (true) { int count = this.selector.select(); if (count == 0) { continue; } Iterator<SelectionKey> it = this.selector.selectedKeys().iterator(); while (it.hasNext()) { final SelectionKey key = it.next(); it.remove(); if (!key.isValid()) { continue; } if (key.isAcceptable()) { this.accept(key); } else if (key.isReadable()) { this.read(key); // Server端用一个线程来处理一个客户端的请求,在read完之后立即向客户端写数据,因此不需要再注册SeletionKey.OP_WRITE // 由于线程是在线程池中来运行的,因此一定要把当然key的SelectionKey.OP_READ事件给取消掉,否则会多次执行read方法 key.interestOps(0); } } } } /** * @param key */ private void accept(SelectionKey key) { try { SocketChannel c = ((ServerSocketChannel) key.channel()).accept(); c.configureBlocking(false); c.register(selector, SelectionKey.OP_READ); this.print(c + "连接成功,并注册READ事件"); } catch (IOException e) { e.printStackTrace(); } } /** * @param key */ private void read(final SelectionKey key) { this.executors.execute(new Runnable() { @Override public void run() { try { int num = -1; SocketChannel c = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); while (c.isOpen()) { num = c.read(buffer); if (num < 1) { break; } buffer.flip(); MyServer.this.put2Map(c, buffer); buffer.clear(); } if (num == -1) { c.close(); key.channel(); print(c + "has been closed"); MyServer.this.channelMap.remove(c); return; } print("从" + c + "读取数据完毕"); if (c.isOpen() && MyServer.this.channelMap.get(c) != null && MyServer.this.channelMap.get(c).length() != 0) { MyServer.this.channelMap.get(c).trimToSize(); String str = "echo: " + MyServer.this.channelMap.get(c); c.write(ByteBuffer.wrap(str.getBytes())); print("向" + c + "写数据完毕"); MyServer.this.put2Map(c, null); // 由于Selector线程中已经取消了OP_READ事件,因此这里再加上OP_READ key.interestOps(SelectionKey.OP_READ); key.selector().wakeup(); } } catch (IOException e) { e.printStackTrace(); key.channel(); try { key.channel().close(); } catch (IOException e1) { e1.printStackTrace(); } } } }); } private void put2Map(SocketChannel channel, ByteBuffer buffer) { if (this.channelMap.get(channel) == null) { this.channelMap.put(channel, new StringBuilder()); } if (buffer == null) { this.channelMap.get(channel).setLength(0); return; } try { this.channelMap.get(channel).append(decoder.decode(buffer).toString()); } catch (CharacterCodingException e) { e.printStackTrace(); } } private void print(String msg) { System.out.println(this.format.format(new Object[] { new Date(), msg })); } }
import java.io.IOException; 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.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.text.MessageFormat; import java.util.Date; import java.util.Iterator; /** * chega * 2012-11-21下午3:19:52 */ /** * @author chega * * 2012-11-21下午3:19:52 * */ public class MyClient { Selector selector; InetSocketAddress address; ByteBuffer buffer; CharsetDecoder decoder; private MessageFormat format = new MessageFormat("{0, time, medium}, {1}"); final String TEST = "ntp"; public static void main(String[] args) throws IOException { MyClient t = new MyClient(); t.selector = Selector.open(); t.address = new InetSocketAddress("localhost", 80); t.buffer = ByteBuffer.allocate(1024); t.decoder = Charset.forName("utf-8").newDecoder(); t.run(); } private void run() throws IOException { this.createNewConnection(); while (true) { try { int selectedCount = selector.select(); if (selectedCount == 0) { continue; } Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key = it.next(); it.remove();// 从己选择键中删除,否则该键一直存在 if (!key.isValid()) { continue; } if (key.isConnectable()) { this.connect(key); } else if (key.isReadable()) { this.read(key); } else if (key.isWritable()) { this.write(key); } } } catch (IOException e) { e.printStackTrace(); } } } /** * @param key * @throws IOException * */ private void connect(SelectionKey key) { try { while (!((SocketChannel) key.channel()).finishConnect()) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } continue; } key.interestOps(SelectionKey.OP_WRITE); print(key.channel() + "连接服务器成功,并注册WRITE事件"); } catch (IOException e) { e.printStackTrace(); print(key.channel() + "连接失败"); System.out.println(((SocketChannel) key.channel()).socket().getLocalPort()); System.exit(-1); } } /** * @param key */ private void write(SelectionKey key) { try { // ((SocketChannel) key.channel()).write(ByteBuffer.wrap("GET / HTTP/1.0\r\n\r\n".getBytes())); ((SocketChannel) key.channel()).write(ByteBuffer.wrap(TEST.getBytes())); key.interestOps(SelectionKey.OP_READ); print(key.channel() + "向服务器完数据完毕,并注册READ事件"); } catch (IOException e) { e.printStackTrace(); print(key.channel() + "写数据发生错误"); try { key.channel().close(); } catch (IOException e1) { e1.printStackTrace(); } } } /** * @param key */ private void read(SelectionKey key) { try { int num = -1; buffer.clear(); while (key.channel().isOpen()) { num = ((SocketChannel) key.channel()).read(buffer); if (num < 1) { break; } buffer.flip(); String result = this.decoder.decode(buffer).toString(); System.out.println(result); buffer.clear(); } // sleep 5s and write again Thread.sleep(5000); key.interestOps(SelectionKey.OP_WRITE); } catch (IOException e) { e.printStackTrace(); print(key.channel() + "读取数据发生错误"); try { key.channel().close(); } catch (IOException e1) { e1.printStackTrace(); } } catch (InterruptedException e) { e.printStackTrace(); } } private void createNewConnection() throws IOException { SocketChannel channel = SocketChannel.open(); channel.configureBlocking(false); channel.connect(address); channel.register(selector, SelectionKey.OP_CONNECT); } private void print(String msg) { System.out.println(this.format.format(new Object[] { new Date(), msg })); } }
发表评论
-
Java String.intern()
2017-09-14 18:44 612在看《深入理解Java虚拟机》第二章中有如下代码: Str ... -
java开发小技巧
2013-02-28 10:06 860前面几篇blog记录的都是java中一些很基础的知识,但不经常 ... -
泛型类不能继承Throwable及其子类
2013-02-22 16:35 1405class A<T> extends Throwa ... -
根据totalRecordSize和pageRecordSize求pageCount
2013-02-18 18:18 968一直使用(totalRecordSize - 1) / pag ... -
maven学习笔记
2013-01-18 18:27 0eclipse运行需要jre环境,在编译java文件时可以没有 ... -
开发规范
2013-01-07 13:25 8171:制定API的时候,一定要考虑到参数类型、方法返回类型和所能 ... -
java异常
2012-12-28 10:30 1185运行时异常可以不捕获,即使一段代码不可能抛出这个Runtime ... -
java NIO通信小例子
2012-12-05 09:53 0Server端代码,selector线程专门负责接收连接,re ... -
java中CyclicBarrier和CountDownLatch的异同
2012-11-23 16:11 1538CountDownLatch只能使用一次,cyclicBarr ... -
Java&Js正则
2012-11-16 16:51 801greedy, reluctant, possessive 三 ... -
java多语言
2012-11-09 15:41 1176在eclipse plugin编程中,可以直接用继承NLS这个 ... -
URL访问文件
2012-11-01 15:57 979try{ // URL url = new URL( ... -
java 正则小知识
2012-10-11 18:43 0(?=X) X, via zero-width positiv ... -
Thinking In Java 4th 关于Annotation处理器的观察者模式
2012-08-13 09:43 1055首先先定义SQLString SQLInteger Const ... -
cxf发布WS,如何在pojo中得到web.xml中配置
2012-08-02 18:48 1134用cxf直接将一个pojo作为WS进行发布,如果想在pojo中 ... -
去除代码行中前面的数字
2012-07-30 10:56 1251在网上看demo,复制代码下来执行,通常前面的行数也一起复制了 ... -
java rmi
2012-07-16 16:02 677==引自http://www.cnblogs.com/nina ... -
java取MAC地址
2012-07-12 11:29 1175jdk1.6中,NetworkInterface这个类提供了g ... -
java压缩与解压缩
2012-07-11 19:31 898public class Test5 { publ ... -
目录递归拷贝(java)
2012-07-11 16:22 1127public class Test4 { privat ...
相关推荐
本文将深入探讨Java NIO中的Selector机制,并通过源码分析来理解其实现原理。 Selector机制是Java NIO中的核心组件,它允许单线程同时监控多个通道(Channels)的状态变化,例如连接就绪、数据可读或可写等。这种...
Selector是Java NIO框架中的核心组件,它使得单个线程能够管理多个通道(Channels),从而提高系统资源利用率并优化性能。下面我们将详细探讨Java NIO中的Selector机制。 1. **Selector的作用** Selector的主要功能...
Selector是Java NIO中的核心组件之一,它允许单个线程处理多个通道(channels)的读写事件,极大地提高了服务器的并发能力。本篇文章将深入探讨如何在Java NIO中使用Selector处理客户端的I/O请求。 首先,我们需要...
Java NIO(Non-Blocking I/O)中,Selector(选择器)是一种重要的组件,它提供了选择执行已经就绪的任务的能力,使得多元 I/O 成为可能。在 Java 中,Selector 是一种抽象类,提供了选择就绪 Task 的能力。 ...
**传统阻塞I/O模型**:在传统的Java IO编程中,当我们调用`read()`或`write()`方法时,如果当前没有数据可读或写,那么这些方法将会阻塞,直到有数据可用或者写操作完成。这种阻塞机制会导致大量的线程被占用,从而...
- **Selector**:选择器是Java NIO中用于监听多个通道事件的关键组件。通过选择器,一个线程可以同时监听多个通道的事件,如数据可读或可写等,从而实现高效处理多个连接的能力。 #### 二、Channels and Buffers ...
**Selector** 是 Java NIO (New I/O) 框架中的一个重要组成部分,主要用于检测一个或多个 **NIO Channel** 的状态,包括但不限于可读、可写、可连接或可接收等状态。它的引入主要是为了克服传统 BIO (Blocking I/O) ...
Java NIO(New Input/Output)是Java标准库中提供的一种I/O模型,与传统的 Blocking I/O(同步阻塞I/O)相对。NIO在Java 1.4版本引入,其设计目标是提供一种更高效、更灵活的I/O操作方式,特别适合处理大量并发连接...
Selector是Java NIO中的核心组件,用于监听多个通道的事件,如连接建立、数据可读、写空等。在服务器端,Selector的应用尤为重要,因为它可以实现单线程处理多个客户端连接,从而提高系统的并发能力。 Selector的...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java平台中用于高效处理I/O操作的重要框架。它在Java 1.4版本中被引入,替代了传统的IO模型,提供了更高级别的I/O操作机制,以适应并发编程的需求...
Java NIO(New Input/Output)是在JDK 1.4中引入的一种新的I/O处理方式,它支持非阻塞模式的文件和套接字操作。NIO的关键组件包括缓冲区(Buffers)、通道(Channels)、选择器(Selectors)等。 **Java NIO的主要...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一个新特性,旨在提供一种更高效、更具选择性的I/O操作方式。相较于传统的IO模型,NIO的核心优势在于其非阻塞特性,允许...
Java NIO(非阻塞I/O)中的Selector是一个核心组件,它允许单个线程处理多个通道(channels)上的I/O事件。Selector的角色就像一个交通指挥员,能够监控多个通道并决定哪个通道准备好进行读写操作,从而提高系统的...
在这个“JAVA nio的一个简单的例子”中,我们将探讨如何使用Java NIO进行简单的服务器-客户端通信,并计算字符串的哈希值。 在传统的BIO模型中,每个连接都需要一个线程来处理,当并发连接数量增加时,系统会创建...
Java NIO 是 Java 平台的一个重要特性,首次出现在 Java 1.4 版本中。它为 Java 开发者提供了一套全新的 I/O 处理方式,相比于传统的 I/O API,新版本提供了更高效、更灵活的解决方案。本书《Java™ NIO》由 Ron ...
Java NIO(New Input/Output)是...本教程“Java基础第27天-03.NIO-Selector.avi”应该会详细讲解这些概念,并通过实际示例展示如何在Java代码中使用Selector来处理I/O事件,帮助学习者深入理解并掌握这一关键技术。
在Java NIO中,数据是以通道(Channels)和缓冲区(Buffers)的形式进行传输,而不是直接通过流。这种设计使得NIO能够同时处理多个输入/输出操作,从而实现多路复用。 标题“nio.rar_NIO_NIO-socket_java nio_java ...
1. **通道(Channel)**:在Java NIO中,通道代表了一个打开的I/O连接,如文件、套接字、网络流等。通道是双向的,数据可以从通道读取,也可以写入。与传统的流不同,通道可以在任何时候进行读写,而无需预先知道...