Java NIO阻塞式通信

package com.nio.t;

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;


/*
 * 一、使用 NIO 完成网络通信的三个核心:
 * 
 * 1. 通道(Channel):负责连接
 *         
 *        java.nio.channels.Channel 接口:
 *             |--SelectableChannel
 *                 |--SocketChannel
 *                 |--ServerSocketChannel   //TCP
 *                 |--DatagramChannel   //UDP
 * 
 *                 |--Pipe.SinkChannel
 *                 |--Pipe.SourceChannel
 * 
 * 2. 缓冲区(Buffer):负责数据的存取
 * 
 * 3. 选择器(Selector):是 SelectableChannel 的多路复用器。用于监控 SelectableChannel 的 IO 状况
 * 
 */
public class TestBlockingNIO {

    //客户端
    public void client() throws IOException{
        //1. 获取通道
        SocketChannel sChannel = SocketChannel.open(
                        new InetSocketAddress("127.0.0.1", 9898));

        //此时文件全部都在FileChannel中
        FileChannel inChannel = FileChannel.open(Paths.get("D:\\1.txt"),
                                    StandardOpenOption.READ);
        
        //2. 分配指定大小的缓冲区
        ByteBuffer buf = ByteBuffer.allocate(1024);
        
        //3. 读取本地文件,并发送到服务端
        while(inChannel.read(buf) != -1){ //FileChannel中的文件读入缓冲区
            buf.flip();
            sChannel.write(buf); //将缓冲区里的数据写入到SocketChannel中
            buf.clear(); //清空缓冲区
        }
        //循环后,文件全部被送入了SocketChannel中
        //4. 关闭通道
        inChannel.close();
        sChannel.close();
    }
    
    //服务端
    public void server() throws IOException{
        //1. 获取通道,表示在本机开了一个ServerSocketChannel通道
        ServerSocketChannel ssChannel = ServerSocketChannel.open();

        //表示在本机创建一个空文件,等待写入数据
        FileChannel outChannel = FileChannel.open(Paths.get("D:\\2.txt"),
                                    StandardOpenOption.WRITE,
                                    StandardOpenOption.CREATE);
        //2. 绑定端口
        ssChannel.bind(new InetSocketAddress(9898));
        
        //3. 获取客户端连接的通道,当与客户端建立好连接后,
        SocketChannel sChannel = ssChannel.accept();
        
        //4. 分配指定大小的缓冲区
        ByteBuffer buf = ByteBuffer.allocate(5);
        
        //5. 接收客户端的数据,并保存到本地
        while(sChannel.read(buf) != -1){
            try {
                Thread.sleep(5000);
            }catch (Exception e){

            }
            buf.flip();
            outChannel.write(buf); //将缓冲区里的数据写入文件
            buf.clear();
        }
        
        //6. 关闭通道
        sChannel.close();
        outChannel.close();
        ssChannel.close();
        
    }

    public static void main(String[] args) {
        new Thread(()->{
            try {
                new TestBlockingNIO().client();
                System.out.println("client end....");
            }catch (Exception e){

            }

        }).start();
        new Thread(()->{
            try {
                new TestBlockingNIO().server();
                System.out.println("server end .....");
            }catch (Exception e){

            }
        }).start();
    }
    
}

猜你喜欢

转载自www.cnblogs.com/wwzyy/p/8964281.html
今日推荐