阻塞式网络通信和非阻塞式网络通信区别

2021-09-26 17:48:17 浏览数 (2)

阻塞式网络通信

代码语言:javascript复制
package NIOAndBIO;

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;

public class BIO {
    public static void main(String[] args) throws IOException {
        Thread thread1 = new Thread(() -> {
            try {
                server();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                client();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        thread1.start();
        thread2.start();
    }

    public static void client() throws IOException {
        // 创建客户端通道
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 2022));

        // 读取信息 D:\bizhi\bizhi202008\wallhaven-kwp2qq.jpg
        FileChannel fileChannel = FileChannel.open(Paths.get("D:\\bizhi\\bizhi202008\\wallhaven-kwp2qq.jpg"), StandardOpenOption.READ);

        // 创建缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        // 写入数据
        while (fileChannel.read(byteBuffer) != -1) {
            byteBuffer.flip();
            socketChannel.write(byteBuffer);
            byteBuffer.clear();
        }

        fileChannel.close();
        socketChannel.close();
    }

    public static void server() throws IOException {
        // 创建服务端通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

        FileChannel fileChannel = FileChannel.open(Paths.get("D:\\bizhi\\bizhi202008\\wallhaven-kwp2qq.jpg"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);

        // 绑定链接
        serverSocketChannel.bind(new InetSocketAddress(2022));

        // 获取客户端的通道
        SocketChannel socketChannel = serverSocketChannel.accept();

        // 创建缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        while (socketChannel.read(byteBuffer) != -1) {
            byteBuffer.flip();
            fileChannel.write(byteBuffer);
            byteBuffer.clear();
        }

        socketChannel.close();
        fileChannel.close();
        serverSocketChannel.close();
    }
}

非阻塞式网络通信

代码语言:javascript复制
package NIOAndBIO;

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;
import java.util.Scanner;

public class NIO {
    public static void main(String[] args) {
        Thread thread1 = new Thread(()->{
            try {
                server();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        Thread thread2 = new Thread(()->{
            try {
                client();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        thread1.start();
        thread2.start();
    }

    public static void client() throws IOException {
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 2020));

        // 设置为非阻塞模式
        socketChannel.configureBlocking(false);

        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String str = scanner.next();
            byteBuffer.put(str.getBytes());
            byteBuffer.flip();
            socketChannel.write(byteBuffer);
            byteBuffer.clear();
        }

        byteBuffer.clear();

        socketChannel.close();
    }

    public static void server() throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.bind(new InetSocketAddress(2020));

        // 获得选择器
        Selector selector = Selector.open();

        // 将通道注册到选择器中,设定为接收操作
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        // 轮询接受
        while (selector.select() > 0) {
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            // 获得事件的key
            while (iterator.hasNext()) {
                SelectionKey key = iterator.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 byteBuffer = ByteBuffer.allocate(10);

                    while (socketChannel.read(byteBuffer) != -1) {
                        int len = byteBuffer.limit();
                        byteBuffer.flip();
                        System.out.println(new String(byteBuffer.array(), 0, len));
                        byteBuffer.clear();
                    }
                    socketChannel.close();
                }
                iterator.remove();
            }
        }
        serverSocketChannel.close();
    }
}

0 人点赞