继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Java入门系列-25-NIO(实现非阻塞网络通信)

慕码人8056858
关注TA
已关注
手记 1293
粉丝 351
获赞 1326

还记得之前介绍NIO时对比传统IO的一大特点吗?就是NIO是非阻塞式的,这篇文章带大家来看一下非阻塞的网络操作。

补充:以数组的形式使用缓冲区

package testnio;import java.io.IOException;import java.io.RandomAccessFile;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;public class TestBufferArray {    public static void main(String[] args) throws IOException {
        RandomAccessFile raf1=new RandomAccessFile("D:/1.txt","rw");        
        //1.获取通道
        FileChannel channel1=raf1.getChannel();        
        //2.创建缓冲区数组
        ByteBuffer buf1=ByteBuffer.allocate(512);
        ByteBuffer buf2=ByteBuffer.allocate(512);
        ByteBuffer[] bufs= {buf1,buf2};        //3.将数据读入缓冲区数组
        channel1.read(bufs);        
        for (ByteBuffer byteBuffer : bufs) {
            byteBuffer.flip();
        }
        System.out.println(new String(bufs[0].array(),0,bufs[0].limit()));
        System.out.println("-----------");
        System.out.println(new String(bufs[1].array(),0,bufs[1].limit()));        
        //写入缓冲区数组到通道中
        RandomAccessFile raf2=new RandomAccessFile("D:/2.txt","rw");
        FileChannel channel2=raf2.getChannel();
        channel2.write(bufs);
        
    }
}

使用NIO实现阻塞式网络通信

TCP协议的网络通信传统实现方式是通过套接字编程(Socket和ServerSocket),NIO实现TCP网络通信需要用到 Channel 接口的两个实现类:SocketChannel和ServerSocketChannel

使用NIO实现阻塞式网络通信

客户端

package com.jikedaquan.blockingnio;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;import java.nio.channels.SocketChannel;import java.nio.file.Paths;import java.nio.file.StandardOpenOption;public class Client {    public static void main(String[] args) {

        SocketChannel sChannel=null;

        FileChannel inChannel=null;        try {            //1、获取通道
            sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 1666));            //用于读取文件            
            inChannel = FileChannel.open(Paths.get("F:/a.jpg"), StandardOpenOption.READ);            //2、分配指定大小的缓冲区
            ByteBuffer buf=ByteBuffer.allocate(1024);            //3、读取本地文件,发送到服务器端

            while(inChannel.read(buf)!=-1) {
                buf.flip();
                sChannel.write(buf);
                buf.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {            //关闭通道
            if (inChannel!=null) {                try {
                    inChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }            if(sChannel!=null) {                try {
                    sChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

new InetSocketAddress("127.0.0.1", 1666) 用于向客户端套接字通道(SocketChannel)绑定要连接地址和端口

服务端

package com.jikedaquan.blockingnio;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 Server {    public static void main(String[] args) {

        ServerSocketChannel ssChannel=null;

        FileChannel outChannel=null;

        SocketChannel sChannel=null;        try {            //1、获取通道
            ssChannel = ServerSocketChannel.open();            //用于保存文件的通道
            outChannel = FileChannel.open(Paths.get("F:/b.jpg"), StandardOpenOption.WRITE,StandardOpenOption.CREATE);            //2、绑定要监听的端口号
            ssChannel.bind(new InetSocketAddress(1666));            //3、获取客户端连接的通道
            sChannel = ssChannel.accept();            //4、分配指定大小的缓冲区
            ByteBuffer buf=ByteBuffer.allocate(1024);            //5、接收客户端的数据,并保存到本地
            while(sChannel.read(buf)!=-1) {
                buf.flip();
                outChannel.write(buf);
                buf.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {            //6、关闭通道
            if(sChannel!=null) {                try {
                    sChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }            if(outChannel!=null) {                try {
                    outChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }            if(ssChannel!=null) {                try {
                    ssChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }   
            }       
        }
    }   
}



作者:极客大全
链接:https://www.jianshu.com/p/7ddccc674cd8


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP