zoukankan      html  css  js  c++  java
  • NIO

    客户端代码

        
    public static void client()
        {
            ByteBuffer buffer = ByteBuffer.allocate(1024);//给buffer缓冲区分配空间
            SocketChannel socketChannel = null;
            try
            {
                socketChannel = SocketChannel.open();//打开socketChannel
                socketChannel.configureBlocking(false);//配置这个信道为非阻塞信道
                socketChannel.connect(new InetSocketAddress(InetAddress.getLocalHost(),8080));//连接服务器
                if(socketChannel.finishConnect())//用来确认通道连接已经建立的
                {
                    int i=0;
                    while(true)
                    {
                        TimeUnit.SECONDS.sleep(1);//延时一秒
                        String info = "I'm "+i+++"-th information from client";
                        buffer.clear();//将buffer中没读的数据遗忘掉(limit又会回到capacity)
                        buffer.put(info.getBytes());//将字符串存如buffer中
                        //调用下面这个函数会让position为0,limit为之前position的值
                        //这样我们只可以读出从position到limit这些位置的数据,也就是之前我们写的数据
                        buffer.flip();
                        while(buffer.hasRemaining()){//判断当前元素是否在限制范围内(positon是否limit)
                            System.out.println(buffer);
                            socketChannel.write(buffer);//将buffer中的数据写如socketChannel中
                        }
                    }
                }
            }
            catch (IOException | InterruptedException e)
            {
                e.printStackTrace();
            }
            finally{
                try{
                    if(socketChannel!=null){
                        socketChannel.close();
                    }
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
        }

    服务器代码:

    public class Main
    {
        private static final int BUF_SIZE=1024;
        private static final int PORT = 8080;
        private static final int TIMEOUT = 3000;
        public static void main(String[] args)
        {
            selector();
        }
        public static void handleAccept(SelectionKey key) throws IOException
        {
            ServerSocketChannel ssChannel = (ServerSocketChannel)key.channel();//获取发生网络事件的ssc
            SocketChannel sc = ssChannel.accept();//通过accept获取SocketChannel
            sc.configureBlocking(false);
            //将sc注册到selector中,注册读事件,同时附加参数为一个申请的1024的buffer空间
            sc.register(key.selector(), SelectionKey.OP_READ, ByteBuffer.allocateDirect(BUF_SIZE));
        }
        public static void handleRead(SelectionKey key) throws IOException{
            SocketChannel sc = (SocketChannel)key.channel();//获取发生网络事件的sc
            ByteBuffer buf = (ByteBuffer)key.attachment();//获取附加参数
            long bytesRead = sc.read(buf);//从Channel中读取数据到buffer中
            while(bytesRead>0){
                buf.flip();
                while(buf.hasRemaining()){
                    System.out.print((char)buf.get());
                }
                System.out.println();
                buf.clear();
                bytesRead = sc.read(buf);//继续读取
            }
            if(bytesRead == -1){//客户端数据发送完毕并主动断开socket
                sc.close();
            }
        }
        public static void handleWrite(SelectionKey key) throws IOException{
            ByteBuffer buf = (ByteBuffer)key.attachment();
            buf.flip();
            SocketChannel sc = (SocketChannel) key.channel();
            while(buf.hasRemaining()){
                sc.write(buf);//通过buffer写入数据到信道中
            }
            buf.compact();//将所有处理的数据拷贝到Buffer起始处。然后将position设到最后一个未读元素正后面。
                          //limit属性依然像clear()方法一样,设置成capacity
        }
        public static void selector() {
            Selector selector = null;//与其一起使用的通道一定是非阻塞的(FileChannel就不行)
            ServerSocketChannel ssc = null;
            try{
                selector = Selector.open();//打开selector
                ssc= ServerSocketChannel.open();//打开SSC(客户端那边是SocketChannel)
                ssc.socket().bind(new InetSocketAddress(PORT));//绑定端口号
                ssc.configureBlocking(false);//设置非阻塞
                SelectionKey s = ssc.register(selector, SelectionKey.OP_ACCEPT);// 选择注册什么事件到selector中
                while(true){
                    if(selector.select(TIMEOUT) == 0){
                        System.out.println("==");
                        continue;
                    }
                    Iterator<SelectionKey> iter = selector.selectedKeys().iterator();//遍历发生事件的sK
                    while(iter.hasNext()){
                        SelectionKey key = iter.next();
                        if(key.isAcceptable()){
                            handleAccept(key);
                        }
                        if(key.isReadable()){
                            handleRead(key);
                        }
                        if(key.isWritable() && key.isValid()){
                            handleWrite(key);
                        }
                        if(key.isConnectable()){
                            System.out.println("isConnectable = true");
                        }
                        iter.remove();
                    }
                }
            }catch(IOException e){
                e.printStackTrace();
            }finally{
                try{
                    if(selector!=null){
                        selector.close();
                    }
                    if(ssc!=null){
                        ssc.close();
                    }
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
        }
    }

     通过nio读取大文件:http://www.sharejs.com/codes/java/1334

  • 相关阅读:
    stm32 IO模式
    stm32的ADC
    bsp
    stm32的硬件调试设置
    RTC实时时钟
    快手2019笔试题 “回文子串" 解题思路
    C++内存修改器开源代码
    FC游戏修改教程(hack)小白文。
    GLFW+GLEW搭建opengl环境(备忘)
    8086 IO读写操作
  • 原文地址:https://www.cnblogs.com/TheQi/p/10459042.html
Copyright © 2011-2022 走看看