netty学习记录(2)

netty学习记录(2)

nio学习:

package com.zhuguozhu.client;

/**
 * nio的客户端
 * @author Guozhu Zhu
 * @date 2018/4/13
 * @version 1.0
 */
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

public class Client {
	    public static void main(String[] args) {
	        InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8379);
	        SocketChannel sc = null;
	        ByteBuffer buffer = ByteBuffer.allocate(1024);
	        try {
	            //打开通道
	            sc = SocketChannel.open();
	            //建立连接
	            sc.connect(address);
	            while (true) {
	                byte[] bytes = new byte[1024];
	                System.in.read(bytes);
	                //把输入的数据放入buffer缓冲区
	                buffer.put(bytes);
	                //复位操作
	                buffer.flip();
	                //将buffer的数据写入通道
	                sc.write(buffer);
	                //清空缓冲区中的数据
	                buffer.clear();
	            }
	        } catch (Exception e) {
	            e.printStackTrace();
	        } finally {
	            if (sc != null) {
	                try {
	                    sc.close();
	                } catch (IOException e) {
	                    e.printStackTrace();
	                }
	            }
	        }
	    }

}
package com.zhuguozhu.p1;

/**
 * IntBufferTest(Buffer常用类)
 * @author Guozhu Zhu
 * @date 2018/1/14
 * @verison 1.0
 */
import java.nio.IntBuffer;

public class IntBufferTest {

    public static void main(String[] args) {
        //1、基本操作
        //创建指定长度的缓冲区
        /*IntBuffer buffer = IntBuffer.allocate(10);
        buffer.put(11); //position位置:0->1
        buffer.put(5); //position位置:1->2
        buffer.put(32); //position位置:2->3
        System.out.println("未调用flip复位方法前的buffer:" + buffer);
        //把位置复位为0,也就是position位置由3->0
        buffer.flip();
        //比较未调用flip方法和调用之后buffer的limit可以发现,不进行复位操作的话,position的值为3,limit的值为10
        // 因为缓冲区中已有11、5、32三个元素,也就意味着put()方法会使position向后递增1
        System.out.println("调用flip复位方法后的buffer:" + buffer);
        System.out.println("buffer容量为:" + buffer.capacity());
        System.out.println("buffer限制为:" + buffer.limit());
        System.out.println("获取下标为1的元素:" + buffer.get(1));
        System.out.println("调用get(index)方法后的buffer:" + buffer); //调用get(index)方法,不会改变position的值
        buffer.put(1, 4); //将buffer位置为1的值替换为4,调用put(index,value)不会改变position的值
        System.out.println("调用put(index, value)方法后的buffer:" + buffer);

        for(int i=0; i<buffer.limit(); i++) {
            //调用get方法会使缓冲区的位置(position)向后递增一位
            System.out.print(buffer.get() + "\t");
        }
        System.out.println("\nbuffer对象遍历之后buffer为:" + buffer);*/


        //2、wrap方法的使用
        /*int[] arr = new int[]{1, 2, 3};
        IntBuffer buffer = IntBuffer.wrap(arr);
        System.out.println("wrap(arr)方法:" + buffer);
        //IntBuffer.wrap(array, postion, length)表示容量为array的长度,但是可操作的元素为位置postion到length的数组元素
        buffer = IntBuffer.wrap(arr, 0, 2);
        System.out.println("wrap(arr, 0, 2):" + buffer);*/

        //3、其他方法
        IntBuffer buffer = IntBuffer.allocate(10);
        int[] arr = new int[]{1, 2, 3};
        buffer.put(arr);
        System.out.println("调用put(arr)方法后的buffer:" + buffer);
        //一种复制方法,buffer1的pos、lim、cap与buffer的一样
        IntBuffer buffer1 = buffer.duplicate();
        System.out.println("buffer1:" + buffer1);

        buffer.position(1); //将buffer的position设置为1,不建议使用。功能相当于flip()方法,但是从运行结果可以看出,lim依然等于10
        System.out.println("调用position()方法后的buffer:" + buffer);
        System.out.println("buffer的可读数据量:" + buffer.remaining()); //计算出从pos到lim的长度
        int[] arr1 = new int[buffer.remaining()];
        //将缓冲区的数据放入arr1中
        buffer.get(arr1);
        for(Integer i : arr1) {
            System.out.print(Integer.toString(i) + ",");
        }
        System.out.println();

        //比较flip()方法和position(index)方法的区别
        buffer1.flip();
        System.out.println("buffer1的可读数量:" + buffer1.remaining());
        arr1 = new int[buffer1.remaining()];
        buffer1.get(arr1);
        for(Integer i : arr1) {
            System.out.print(Integer.toString(i) + ",");
        }
    }
}



package com.zhuguozhu.server;

/**
 * nio的服务器端
 * @author Guozhu Zhu
 * @date 2018/4/13
 * @version 1.0
 */
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.Iterator;

public class Server implements Runnable {

	    private Selector selector;
	    
	    private ByteBuffer buffer = ByteBuffer.allocate(1024);

	    public Server(int port) {
	        try {
	            //1 打开多路复用器
	            selector = Selector.open();
	            //2 打开服务器通道
	            ServerSocketChannel ssc = ServerSocketChannel.open();
	            //3 设置服务器通道为非阻塞方式
	            ssc.configureBlocking(false);
	            //4 绑定地址
	            ssc.bind(new InetSocketAddress(port));
	            //5 把服务器通道注册到多路复用选择器上,并监听阻塞状态
	            ssc.register(selector, SelectionKey.OP_ACCEPT);
	            System.out.println("Server start, port:" + port);
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	    }

	    @Override
	    public void run() {
	        while (true) {
	            try {
	                //1 必须让多路复用选择器开始监听
	                selector.select();
	                //2 返回所有已经注册到多路复用选择器上的通道的SelectionKey
	                Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
	                //3 遍历keys
	                while (keys.hasNext()) {
	                    SelectionKey key = keys.next();
	                    keys.remove();
	                    if (key.isValid()) { //如果key的状态是有效的
	                        if(key.isAcceptable()) { //如果key是阻塞状态,则调用accept()方法
	                            accept(key);
	                        }
	                        if(key.isReadable()) { //如果key是可读状态,则调用read()方法
	                            read(key);
	                        }
	                    }
	                }
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	    }

	    private void accept(SelectionKey key) {
	        try {
	            //1 获取服务器通道
	            ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
	            //2 执行阻塞方法
	            SocketChannel sc = ssc.accept();
	            //3 设置阻塞模式为非阻塞
	            sc.configureBlocking(false);
	            //4 注册到多路复用选择器上,并设置读取标识
	            sc.register(selector, SelectionKey.OP_READ);
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	    }

	    private void read(SelectionKey key) {
	        try {
	            //1 清空缓冲区中的旧数据
	            buffer.clear();
	            //2 获取之前注册的SocketChannel通道
	            SocketChannel sc = (SocketChannel) key.channel();
	            //3 将sc中的数据放入buffer中
	            int count = sc.read(buffer);
	            if(count == -1) { // == -1表示通道中没有数据
	                key.channel().close();
	                key.cancel();
	                return;
	            }
	            //读取到了数据,将buffer的position复位到0
	            buffer.flip();
	            byte[] bytes = new byte[buffer.remaining()];
	            //将buffer中的数据写入byte[]中
	            buffer.get(bytes);
	            String body = new String(bytes).trim();
	            System.out.println("Server:" + body);
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	    }

	    public static void main(String[] args) {
	        new Thread(new Server(8379)).start();
	    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值