- 浏览: 184306 次
- 性别:
- 来自: 苏州
文章分类
最新评论
-
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 555在看《深入理解Java虚拟机》第二章中有如下代码: Str ... -
java开发小技巧
2013-02-28 10:06 812前面几篇blog记录的都是java中一些很基础的知识,但不经常 ... -
泛型类不能继承Throwable及其子类
2013-02-22 16:35 1344class A<T> extends Throwa ... -
根据totalRecordSize和pageRecordSize求pageCount
2013-02-18 18:18 926一直使用(totalRecordSize - 1) / pag ... -
maven学习笔记
2013-01-18 18:27 0eclipse运行需要jre环境,在编译java文件时可以没有 ... -
开发规范
2013-01-07 13:25 7811:制定API的时候,一定要考虑到参数类型、方法返回类型和所能 ... -
java异常
2012-12-28 10:30 1096运行时异常可以不捕获,即使一段代码不可能抛出这个Runtime ... -
java NIO通信小例子
2012-12-05 09:53 0Server端代码,selector线程专门负责接收连接,re ... -
java中CyclicBarrier和CountDownLatch的异同
2012-11-23 16:11 1467CountDownLatch只能使用一次,cyclicBarr ... -
Java&Js正则
2012-11-16 16:51 765greedy, reluctant, possessive 三 ... -
java多语言
2012-11-09 15:41 1112在eclipse plugin编程中,可以直接用继承NLS这个 ... -
URL访问文件
2012-11-01 15:57 906try{ // 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 1012首先先定义SQLString SQLInteger Const ... -
cxf发布WS,如何在pojo中得到web.xml中配置
2012-08-02 18:48 1078用cxf直接将一个pojo作为WS进行发布,如果想在pojo中 ... -
去除代码行中前面的数字
2012-07-30 10:56 1219在网上看demo,复制代码下来执行,通常前面的行数也一起复制了 ... -
java rmi
2012-07-16 16:02 620==引自http://www.cnblogs.com/nina ... -
java取MAC地址
2012-07-12 11:29 1130jdk1.6中,NetworkInterface这个类提供了g ... -
java压缩与解压缩
2012-07-11 19:31 862public class Test5 { publ ... -
目录递归拷贝(java)
2012-07-11 16:22 1087public class Test4 { privat ...
相关推荐
NIO其核心概念包括Channel,Selector,SelectionKey,Buffer.
NIO 有一个主要的类Selector,这个类似一个观察者,只要我们把需要探知的socketchannel告诉Selector,我们接着做别的事情,当有事件发生时,他会通知我们,传回一组SelectionKey,我们读取这些Key,就会获得我们刚刚注册...
import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.util.Iterator; import com.nio.user.ClientUser; import ...
java.nio包提供了支持非阻塞通信的类,主要包括: ● ServerSocketChannel:ServerSocket的替代类,支持阻塞通信与非阻塞通信。 ● SocketChannel:Socket的替代类,支持阻塞通信与非阻塞通信。 ● Selector:为...
即需要采用SelectionKey.cancel()从注册的Selector中取消对该Selection的监视,防止同时多个线程获取到SelectionKey的事件 2.注册在向Selector注册通道的时候,如果register方法抛出KeyCancelledException表明,...
Selector类似一个调度中心,所有Channel都需要注册到选择器中,并绑定一个SelectionKey,绑定时还会指定要监听的事件,如:连接就绪、读就绪、写就绪等。可以调用Selector提供的API实现对发生监听事件的连接进行处理...
import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.ByteBuffer; import java.io.RandomAccessFile; import java.io.FileOutputStream; import java.io.File; import ...
具体通信流程 1.客户端连接服务端,服务端通过Selector接收到连接请求,将其socketChannel通道保存到通道集合,并触发客户端连接事件 2.客户端发送数据包请求到服务端,服务端将...若要深入了解,请先了解Java NIO技术
NIO网络编程 Selector选择器 进行监听,是新连接或已经连接,读写数据 常用方法 public static Selector Open(); 得到一个选择器对象 public int select(long timeout); 监听所有注册通道,存在IO流操作,将对应...
1. NIO完成网络编程 1.1 Selector选择器老大 Selector 选择器,网络编程使用NIO的大哥!!! 服务器可以执行一个线程,运行Selector程序,进行监听操作。 新连接, 已经连接, 读取数据,写入数据 Selector常用...
NIO完成网络编程 1. Selector——选择器老大 ... 监听所有注册通道,存在IO流操作是,会将对应的信息SelectionKey存入到内部的集合中,参数是一个超时时间 public Set selectionKeys(); 返回当前Se
NioSocket中服务端的处理过程可以分为5部: 1) 创建ServerSocketChannel,并设置相应参数 2) 创建Selector并注册到ServerSocketChannel上 3) 调用Selector的select方法等待请求 4) Selector接收到请求后使用...