zoukankan      html  css  js  c++  java
  • 基于NIO写的阻塞式和非阻塞式的客户端服务端

    由于功能太过简单,就不过多阐述了,直接上阻塞式代码:

    package com.lql.nio;
    
    import org.junit.Test;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.nio.file.Paths;
    import java.nio.file.StandardOpenOption;
    
    /**
     * @author: lql
     * @date: 2019.11.01
     * Description: 客户端发送一条数据给服务端,服务端接收后反馈一条信息
     */
    public class TestBlockingNIO2 {
    
        @Test
        public void client() {
            SocketChannel socketChannel = null;
            FileChannel inChannel = null;
            try {
                //获取通道
                socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8002));
                inChannel = FileChannel.open(Paths.get("2.png"), StandardOpenOption.READ);
    
                //获取缓冲区
                ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
    
                while (inChannel.read(byteBuffer) != -1) {
                    byteBuffer.flip();
                    socketChannel.write(byteBuffer);
                    byteBuffer.clear();
                }
    
                //切断
                socketChannel.shutdownOutput();
    
                //接收服务器端的反馈
                int len = 0;
                while ((len = socketChannel.read(byteBuffer)) != -1) {
                    byteBuffer.flip();
                    System.out.println(new String(byteBuffer.array(), 0, len));
                    byteBuffer.clear();
                }
    
    
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (inChannel != null) {
                    try {
                        inChannel.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (socketChannel != null) {
                    try {
                        socketChannel.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
    
        @Test
        public void server() {
            ServerSocketChannel serverSocketChannel = null;
            FileChannel outChannel = null;
            try {
                serverSocketChannel = ServerSocketChannel.open();
                outChannel = FileChannel.open(Paths.get("wy.png"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
    
                SocketChannel socketChannel = serverSocketChannel.bind(new InetSocketAddress("127.0.0.1", 8002)).accept();
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                while (socketChannel.read(buffer) != -1) {
                    buffer.flip();
                    outChannel.write(buffer);
                    buffer.clear();
                }
    
                //接收完发送反馈给客户端
                buffer.put("服务器端接收客户端数据成功!!!".getBytes());
                buffer.flip();
                socketChannel.write(buffer);
    
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (outChannel != null) {
                    try {
                        outChannel.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (serverSocketChannel != null) {
                    try {
                        serverSocketChannel.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
    }

     接来下是非阻塞式的代码:

    package com.lql.nio;
    
    import org.junit.Test;
    
    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.time.LocalDateTime;
    import java.util.Iterator;
    
    /**
     * @author: lql
     * @date: 2019.11.01
     * Description: 非阻塞式(得有Channel,Buffer,Selector)
     */
    public class TestNonBlockingNIO {
    
        //客户端
        @Test
        public void client() {
            SocketChannel socketChannel = null;
            try {
                //获取通道
                socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8006));
                //切换成非阻塞模式
                socketChannel.configureBlocking(false);
                //获取缓冲区
                ByteBuffer buf = ByteBuffer.allocate(1024);
                //发送数据给服务端
                buf.put(LocalDateTime.now().toString().getBytes());
                buf.flip();
                socketChannel.write(buf);
                buf.clear();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (socketChannel != null) {
                    try {
                        socketChannel.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    
    
        }
    
    
        @Test
        public void Server() {
    
            ServerSocketChannel serverSocketChannel = null;
            try {
                serverSocketChannel = ServerSocketChannel.open();
                //切换非阻塞模式
                serverSocketChannel.configureBlocking(false);
                //绑定并接收
                serverSocketChannel.bind(new InetSocketAddress("127.0.0.1", 8006));
                //获取选择器
                Selector selector = Selector.open();
                //将通道注册到选择器上,指定监听“接收”事件
                serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    
                //轮询式的获取选择器上已经“准备就绪”的事件
                while (selector.select() > 0) {
                    //获取所有监听的事件
                    Iterator<SelectionKey> it = selector.selectedKeys().iterator();
    
                    while (it.hasNext()) {
                        //获取准备就绪的事件
                        SelectionKey key = it.next();
    
                        //判断具体是什么事件准备就绪
                        if (key.isAcceptable()) {
                            //获取客户端链接
                            SocketChannel socketChannel = serverSocketChannel.accept();
    
                            //客户端通道切换成非阻塞
                            socketChannel.configureBlocking(false);
    
                            //将该通道注册要选择器上
                            socketChannel.register(selector, SelectionKey.OP_READ);
                        } else if (key.isReadable()) {
                            //获取读就绪状态的通道
                            SocketChannel socketChannel = (SocketChannel) key.channel();
    
                            //读取数据
                            ByteBuffer buffer = ByteBuffer.allocate(1024);
                            int len = 0;
                            while ((len = socketChannel.read(buffer)) != -1) {
                                buffer.flip();
    
                                System.out.println(new String(buffer.array(), 0, len));
                                buffer.clear();
                            }
    
                        }
                        //取消选择键
                        it.remove();
                    }
    
                }
    
    
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
    
            }
    
    
        }
    
    }
  • 相关阅读:
    hdu_1052 Tian Ji -- The Horse Racing 贪心
    hdu_1050 Moving Tables 贪心
    模拟退火算法-旅行商问题-matlab实现
    主成分分析与逐步回归分析的区别
    二叉树--后序遍历的非递归算法
    表达式求值--数据结构C语言算法实现
    线性表—单链表的创建、查询、插入、删除、合并
    线性表--顺序线性表-基本操作:建表,插入,删除
    String、String[]、ArrayList<String>之间的转换
    Java反射机制概念及使用
  • 原文地址:https://www.cnblogs.com/-qilin/p/11778837.html
Copyright © 2011-2022 走看看