NIO SocketChannel simple demo

/**
 * nio 客户端
 * @author Administrator
 *
 */
public class NIOClient implements Runnable{

    private Logger  logger=LoggerFactory.getLogger("nio client");
    
    private String host="127.0.0.1";
    private int port=7001;
    private SocketAddress server;
    private Selector selector; 
    private SocketChannel sc; 
    private ByteBuffer buffer; 
    
    public NIOClient(String host,int port) throws IOException {    
        this.host=host;
        this.port=port;
        server=new InetSocketAddress(host,port);
        selector=Selector.open();
        buffer=ByteBuffer.allocate(100);
    }
    public NIOClient() throws IOException {        
        server=new InetSocketAddress(host,port);
        selector=Selector.open();
        buffer=ByteBuffer.allocate(100);
    }
    private void connect() {
        try {
            logger.info("建立连接.......");
            if(sc!=null)sc.close();//断开重连
            sc=SocketChannel.open();
            sc.configureBlocking(false);
            //sc.setOption(name, value);
            //System.out.println(sc.getOption(StandardSocketOptions.SO_RCVBUF));
            //sc.setOption(name, value)
            //sc.setOption(StandardSocketOptions.SO_RCVBUF, 100);
            //System.out.println(sc.getOption(StandardSocketOptions.SO_RCVBUF));
            sc.socket().setSoTimeout(1000);
            sc.socket().setReceiveBufferSize(100);
            sc.connect(server);
            sc.register(selector, SelectionKey.OP_CONNECT);            
        }catch(IOException e) {
            logger.info("连接失败:"+e.toString());
        }
    }
    @Override
    public void run() {
        connect();
        while(true) {
            try {
                selector.select(1000);
            } catch (IOException e) {
                logger.info("提取select信号失败:"+e.toString());  
            }
            Iterator<SelectionKey> iter=selector.selectedKeys().iterator();
            while(iter.hasNext()) {
                SelectionKey key=iter.next();
                iter.remove();
                if(key.isConnectable()) {
                    try {
                        sc.finishConnect();
                        //sc.configureBlocking(true);
                        write();
                    }catch(Exception e) {
                        logger.info("建立链接异常:"+e.toString()); 
                        connect();                        
                    }
                }else if(key.isReadable()) {
                    try {
                        read();
                    } catch (IOException e) {
                        logger.info("读取数据异常:"+e.toString()); 
                        connect();
                    }
                }            
            }    
        }
    }
    private void write() throws IOException {
        //buffer.clear();
        buffer.put("welcome\n\r".getBytes());
        buffer.flip();
        while(buffer.hasRemaining()){
             sc.write(buffer);
        }
        sc.register(selector, SelectionKey.OP_READ);
    }
    private void read() throws IOException {
        buffer.clear();
        //buffer.flip();
        int flag=0,counter=0;
        while(true) {
            flag=sc.read(buffer);
            counter+=flag;
            //if(buffer.remaining()==0) break;
            System.out.println(flag+" "+counter+" "+buffer.remaining());
            if(flag==0)break;
            //buffer.clear();
        }
        if(counter>0) {
            buffer.flip();
            byte[] read=new byte[counter];
            //("缓冲区: "+readCounter+"  "+read.length);
            buffer.get(read,0,read.length);
            String expression=new String(read,"utf-8");
            System.out.println(expression);                        
            buffer.flip();
            sc.write(buffer);
        }
    }    
    public static void main(String[] args) throws IOException {
        NIOClient client=new NIOClient();
        ExecutorService exec=Executors.newCachedThreadPool();
        exec.submit(client);
    }
}

socketchannel 关键参数说明:

1、socket().setSoTimeout(1000) ;                   read 超时时间 单位毫秒
2、socket().setReceiveBufferSize(100);         read 缓冲区尺寸 

3、ByteBuffer.clear();                                   buffer limit = capacity;position = 0;mark = -1

4、ByteBuffer.flip();                                      buffer limit = position;position=0;mark = -1

5、ByteBuffer.rewind()                                    buffer position=0 

读流程: 

            1、buffer.clear();

            2、读取数据 flag=sc.read(buffer);   flag==0 结束读取 

            3、buffer.flip(); 处理数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值