posts - 28,  comments - 15,  trackbacks - 0
    在读Amoeba源码的时候,里面采用java NIO进行通信管理,以前也了解过一些关于这方面的知识但是都不太系统,最近两天抽时间对这块进行一下扫盲。我主要参考以下两篇文章,个人认为这两篇文章还是不错的入门级文章,讲的比较通俗易懂。
1.http://www.ibm.com/developerworks/cn/education/java/j-nio/section11.html
比较系统的讲述了Channel(通道)、Buffer(缓冲区)、position,limit,capacity in buffer等;其示例代码在:
http://code.google.com/p/astudy/source/browse/trunk/applications/astudy/nio/MultiPortEcho.java?spec=svn141&r=141

2.http://tutorials.jenkov.com/java-nio/index.html
这个站点也是一个不错的入门级别介绍,虽然是e文,但讲解的比较细致。

3.我的demo
这个小例子,模拟了一个echo服务,客户端向echo服务器发送一段信息,echo收到信息后,返回给客户端,然后,连接关闭。代码如下:
/***************************************/
客户端代码:
package com.zxl.channel;

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.util.Set;

public class EchoClient {

    
/**
     * 
@param args
     * 
@throws IOException 
     
*/

    
public static void main(String[] args) throws IOException {
        
        
        SocketChannel channel 
= SocketChannel.open();
        channel.configureBlocking(
false);    
        InetSocketAddress s 
= new InetSocketAddress("localhost",2000);
        channel.connect(s);
        
        Selector selector 
= Selector.open();
        channel.register(selector, SelectionKey.OP_CONNECT
|SelectionKey.OP_READ);
        
        Charset charset
=Charset.forName("GBK");
        
        
boolean isFinished = false;
        
while(!isFinished){
            
int num = selector.select();
            
if(num>0){
                Set
<SelectionKey> keys = selector.selectedKeys();
                
for(SelectionKey k:keys){
                    
if(k.isConnectable()){
                        SocketChannel sc 
= (SocketChannel) k.channel();
                        sc.configureBlocking(
false);
                        sc.finishConnect();
                        sc.register(selector, SelectionKey.OP_READ);
                
                        ByteBuffer echoBuffer 
= ByteBuffer.allocate(1024);
                        ByteBuffer info 
=charset.encode("好了克隆技术杜洛克防水堵漏开发!");
                        echoBuffer.put(info);
                        
                        echoBuffer.flip();    
                    
                        sc.write(echoBuffer);
                        echoBuffer.clear();
                        
                    }
else if (k.isValid() && k.isReadable()) {
                        ByteBuffer echoBuffer 
= ByteBuffer.allocate(1024);
                        SocketChannel sc 
= (SocketChannel) k.channel();
                        sc.read(echoBuffer);
                        echoBuffer.flip();
                        
                        System.out.println(
"echo server return:"+charset.decode(echoBuffer).toString());
                        echoBuffer.clear();
                        
                        isFinished 
= true;
                        
                        k.cancel();
                        sc.close();
                        selector.close();
                    }

                }

            }
    
        }

    }

}


/*********************************************/
服务端代码:

package com.zxl.channel;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
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.Charset;
import java.util.Iterator;
import java.util.Set;

public class MultiPortEchoServer {

    
private Charset charset=Charset.forName("GBK");
    
    
private int[] ports;
    
    
/**
     * 
@param args
     
*/

    
public static void main(String[] args) {
        
        
int[] ps = {2000,2001};   //默认监听2000,2001端口
        
        
new MultiPortEchoServer(ps);

    }

    
    
public MultiPortEchoServer(int[] ports){
        
this.ports = ports;
        
try {
            go();
        }
 catch (IOException e) {
            
// TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    
    
public void go() throws IOException{
        
        Selector selector 
= Selector.open();
        
        
for(int i=0;i<ports.length;i++){
            ServerSocketChannel channel 
= ServerSocketChannel.open();
            channel.configureBlocking(
false);
            ServerSocket socket 
= channel.socket();
            InetSocketAddress address 
= new InetSocketAddress("localhost",ports[i]);
            socket.bind(address);
            
            
//注册接受连接事件
            channel.register(selector, SelectionKey.OP_ACCEPT);
            
            System.out.println( 
"Going to listen on "+ports[i] ); 
        }

        
        
while(true){
            
            
int num = selector.select();
            Set
<SelectionKey> keys = selector.selectedKeys();
            Iterator
<SelectionKey> iter = keys.iterator();
            
while(iter.hasNext()){
                SelectionKey key 
= iter.next();
                
if((key.readyOps()&SelectionKey.OP_ACCEPT)==SelectionKey.OP_ACCEPT){
                    ServerSocketChannel  ssc 
= (ServerSocketChannel) key.channel();
                    SocketChannel sc 
= ssc.accept();
                    sc.configureBlocking(
false);
                    
                    sc.register(selector, SelectionKey.OP_READ);
                    iter.remove();
                }
else if((key.readyOps()&SelectionKey.OP_READ)==SelectionKey.OP_READ){
                    
                    SocketChannel sc 
= (SocketChannel) key.channel();
                    
                    
if(!sc.isOpen()){
                        selector 
= Selector.open();
                    }
else{
                        ByteBuffer echoBuffer 
= ByteBuffer.allocate(1024);  
                        
                        
//int x = sc.read(echoBuffer);
                        while(sc.read(echoBuffer)>0){
                            
                            System.out.println( 
"Echoed "+charset.decode(echoBuffer).toString()+" from "+sc.socket().getInetAddress().getHostAddress() );  
                            echoBuffer.flip();
                            sc.write(echoBuffer);
                            echoBuffer.clear();
                        }

                        
                        
                        iter.remove();
                        
                        
/*返回信息后关闭连接*/
                        key.cancel();
                        sc.close();
                    }

                }

            }

            
            keys.clear();
        }

    }


}




posted on 2011-06-30 16:24 zhangxl 阅读(2781) 评论(1)  编辑  收藏 所属分类: java concurrency


FeedBack:
# re: Java NIO Demo
2014-11-24 09:47 | zuidaima
java demo学习实例教程源代码下载:http://zuidaima.com/share/kjava-p1-s1.htm  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 
<2011年6月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

常用链接

留言簿(1)

随笔分类(17)

随笔档案(28)

文章分类(30)

文章档案(30)

相册

收藏夹(2)

hibernate

java基础

mysql

xml

关注

压力测试

算法

最新随笔

搜索

  •  

积分与排名

  • 积分 - 95547
  • 排名 - 602

最新评论

阅读排行榜

评论排行榜