SocketChannel 例子2_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > SocketChannel 例子2

SocketChannel 例子2

 2012/4/5 13:24:25  youzifei  程序员俱乐部  我要评论(0)
  • 摘要:JavaNIO非堵塞技术实际是采取Reactor模式,或者说是Observer模式为我们监察I/O端口,如果有内容进来,会自动通知我们。在服务端我们可以使用非阻塞的方式。下面是一段server端的程序。client可以采用阻塞方式来请求。NIO有一个主要的类Selector,这个类似一个观察者,只要我们把需要探知的socketchannel告诉Selector,我们接着做别的事情,当有事件发生时,他会通知我们,传回一组SelectionKey,我们读取这些Key
  • 标签:例子 socket

Java NIO非堵塞技术实际是采取Reactor模式,或者说是Observer模式为我们监察I/O端口,如果有内容进来,会自动通知我们。

服务端我们可以使用非阻塞的方式。 下面是一段server端的程序。 client 可以采用阻塞方式来请求。

?

NIO 有一个主要的类Selector,这个类似一个观察者,只要我们把需要探知的socketchannel告诉Selector,我们接着做别的事情,当有事件发生时,他会通知我们,传回一组SelectionKey, 我们读取这些Key, 就会获得我们刚刚注册过的socketchannel,然后,我们从 这个Channel中读取数据,放心,包准能够读到,接着我们可以处理这些数据。

Selector内部原理实际是在做一个对所注册的channel的轮询访问,不断的轮询(目前就这一个算法),一旦轮询到一个channel有所注册的事情发生,比如数据来了,他就会站起来报告,交出一把钥匙,让我们通过这把钥匙来读取这个channel的内容。

?

做一个备忘吧。

?

package com.jimmy.nio;

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.util.Date;
import java.util.Iterator;

public class NoBlockServerSocket {

??? private Selector selector;

??? private ByteBuffer byteBuffer=ByteBuffer.allocate(1024);

??? public NoBlockServerSocket(int port) throws IOException {
??????? selector=Selector.open();
??????? ServerSocketChannel serverSocketChannel=ServerSocketChannel.open();//创建nio通道
??????? serverSocketChannel.socket().bind(new InetSocketAddress(port));//创建基于nio通道的socket链接绑定
??????? serverSocketChannel.configureBlocking(false);//配置使通道不阻塞
??????? serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);//将通道绑定到选择器
??? }

??? public Selector getSelector() {
??????? return selector;
??? }

??? public void setSelector(Selector selector) {
??????? this.selector=selector;
??? }

??? public void listen() {

??????? try {
??????????? for(;;) {

??????????????? int i=selector.select();//获取通道内关心事件的集合。
??????????????? if(i<1){
??????????????????? continue;
??????????????? }
??????????????? //Selector传回一组SelectionKeys
??????????????? Iterator<SelectionKey> iter=selector.selectedKeys().iterator();
??????????????? if(iter.hasNext()) {
??????????????????? SelectionKey selectionKey=iter.next();
??????????????????? //一个key被处理完成后,就都被从就绪关键字(ready keys)列表中除去
??????????????????? iter.remove();
??????????????????? process(selectionKey);
??????????????? }
??????????????? System.out.println(" loop " + new Date());
??????????? }
??????? } catch(IOException e) {
??????????? // TODO Auto-generated catch block
??????????? e.printStackTrace();
??????? }
??? }

??? public void process(SelectionKey selectionKey) throws IOException {
??????? System.out.println("selectionKey.isAcceptable()"+selectionKey.isAcceptable());
??????? System.out.println("selectionKey.isReadable()"+selectionKey.isReadable());
??????? System.out.println("selectionKey.isWritable()"+selectionKey.isWritable());
???????
??????? if(selectionKey.isAcceptable()) {//获得客户端链接,并注册到选择器中,观察的动作有读写。
??????????? ServerSocketChannel server=(ServerSocketChannel)selectionKey.channel();
??????????? SocketChannel socketChannel=server.accept();
??????????? socketChannel.configureBlocking(false);
??????????? socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
??????????? System.out.println("accept:" + selectionKey.interestOps() + " " + selectionKey.readyOps());
??????? } else if(selectionKey.isReadable()) {//这个通道是一个可读的状态。进行读取操作
??????????? SocketChannel channel=(SocketChannel)selectionKey.channel();
??????????? int count=channel.read(byteBuffer);
??????????? if(count > 0) {
??????????????? byteBuffer.flip();
??????????????? byte[] bbb=byteBuffer.array();
??????????????? System.out.println("i receive" + new String(bbb, 0, count));
??????????????? byteBuffer.clear();
??????????? }
??????? } else if(selectionKey.isWritable()) {//这个通道是一个可以写的状态,进行写入的操作
??????????? System.out.println("isWritable:" + selectionKey.interestOps());
??????????? SocketChannel channel=(SocketChannel)selectionKey.channel();
??????????? byteBuffer.clear();
??????????? byteBuffer.put(new Date().toString().getBytes());
??????????? byteBuffer.flip();
??????????? channel.write(byteBuffer);
??????????? channel.close();
??????????? byteBuffer.clear();
??????? }
??????? System.out.println("\n\n\n");
??? }

??? public static void main(String[] args) {
??????? int port=8888;
??????? try {
??????????? NoBlockServerSocket server=new NoBlockServerSocket(port);
??????????? System.out.println("listening on " + port);
??????????? server.listen();
??????? } catch(IOException e) {
??????????? e.printStackTrace();
??????? }
??? }
}

?

?

发表评论
用户名: 匿名