你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

关于Java I/O 模型的个人理解(二)代码

2021/11/6 20:14:00

1.BIO 

客户端简单编写

public static void main(String[] args) {

    try {
        //1.创建socket对象
        Socket socket=new Socket("127.0.0.1", 9999);
        //2.从socket 获取字节输入流
        OutputStream out=socket.getOutputStream();
       //字节输入流换成打印流
        PrintStream ps=new PrintStream(out,true);
        Scanner san=new Scanner(System.in);
        while (true){
            System.out.print("请说:");
            ps.println(san.nextLine()) ;

        }


    } catch (IOException e) {
        e.printStackTrace();
    }

}

服务端简单编写

public static void main(String[] args) {

    try {
        System.out.println("开始注册端口");
        //注册端口
        ServerSocket serversocket=new ServerSocket(9999);
        //循环获取socket 监听
        while(true){
            Socket so=serversocket.accept();

            new ServerThread(so).start();

        }


    } catch (Exception e) {
        e.printStackTrace();
    }
}

定义一个ServerThread线程类

public class ServerThread extends Thread{
    private Socket socket;

    public ServerThread(Socket so) {
        this.socket=so;

    }

    @Override
    public void run() {
        try {
            InputStream input=socket.getInputStream();

            BufferedReader read=new BufferedReader(new InputStreamReader(input));
            String msg;
            while( (msg=read.readLine())!=null ){

                System.out.println(msg);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

2. NIO 代码开发,同样也是实现客户端和服务端交互

客户端:

public class Client {
    //1.选择器
    private Selector selector;
    //2.客户端通道
    private SocketChannel socketChannel;
    //3.端口
    private static int PORT = 9998;
    //4.IP
    private static String IP="127.0.0.1";

    //5.实例化
    public Client(){

        try {
            //6.开启选择器
            selector=Selector.open();
            //7.开启通道
            socketChannel=SocketChannel.open(new InetSocketAddress(IP,PORT));
            //8.设置非阻塞
            socketChannel.configureBlocking(false);
            //9.绑定端口IP
          //  socketChannel.bind(new InetSocketAddress(IP,PORT));
            //10 监听读事件
            socketChannel.register(selector, SelectionKey.OP_READ);
            System.out.println("客户端准备好了");
        } catch (IOException e) {
            System.out.println("客户端连接失败");
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {

        Client client=new Client();
        System.out.println("转发线程启动");
        new Thread(() -> {
            System.out.println("开始转发");
            client.readInfo();
        }).start();

        Scanner sc=new Scanner(System.in);
        while (sc.hasNext()){
          String msg=  sc.nextLine();
          client.writrToServer(msg);
            System.out.println("-------------");
        }

    }

    private void writrToServer(String msg) {

        try {
            socketChannel.write(ByteBuffer.wrap(msg.getBytes()));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private void readInfo() {

            try {
                while(selector.select()>0) {
                    Iterator<SelectionKey> it =selector.selectedKeys().iterator();

                    while(it.hasNext()){
                        //取数
                        SelectionKey sk=it.next();

                        if(sk.isReadable()){
                            SocketChannel sc= (SocketChannel) sk.channel();
                            ByteBuffer bf=ByteBuffer.allocate(1024);
                            sc.read(bf);
                            bf.flip();
                            System.out.println(new String(bf.array(),0,bf.remaining()));
                            System.out.println("----转发结束---------");

                        }
                        it.remove();
                    }

                }
            } catch (IOException e) {
                e.printStackTrace();
            }



    }


}

服务端:

public class Server {
    //1.
    private ServerSocketChannel sschannel;
    //2.
    private Selector selector;
    //3.定义端口
    private final int PORT=9998;
    //构造器
    public Server(){

        try {
            //开启选择器,初始化选择器
            selector=Selector.open();
            //开启通道
            sschannel=ServerSocketChannel.open();
            //设置非阻塞
            sschannel.configureBlocking(false);
            //设置连接
            sschannel.bind(new InetSocketAddress(PORT));
            //注册连接事件
            sschannel.register(selector, SelectionKey.OP_ACCEPT);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void connect() {
        try {
            System.out.println("服务端准备就绪");
            //有连接的事件就一直循环等待
            while (selector.select()>0){
                //迭代所有事件
                Iterator<SelectionKey> it=selector.selectedKeys().iterator();
                while (it.hasNext()){
                    //获取当前事件
                    SelectionKey sk= it.next();
                    //判断事件状态
                    if(sk.isAcceptable()){
                        //11.获取当前接入客户端通道
                        SocketChannel sc= sschannel.accept();
                        //设置事件通道阻塞
                        sc.configureBlocking(false);
                        //13.本客户端注册读事件到选择器
                        sc.register(selector,SelectionKey.OP_READ);

                    }else if(sk.isReadable()){

                        clientGetData(sk);





                    }

                   it.remove();
                }

            }
        }catch (Exception e){

        }


    }

    private void clientGetData(SelectionKey sk) {
        //获取当前事件通道
        SocketChannel socketChannel= null;
        //分配空间
        ByteBuffer bf=ByteBuffer.allocate(1024);

        try {
            socketChannel= (SocketChannel) sk.channel();


            int leg=socketChannel.read(bf);
            if(leg>0){
                bf.flip();
                String msg=new String(bf.array(),0,bf.remaining());
                System.out.println("客户端接收消息:"+msg);
                sendMsgAllclient(msg,socketChannel);

            }

        } catch (IOException e) {
            System.out.println("有人离线了");

            try {
                sk.cancel();
                socketChannel.close();
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
            e.printStackTrace();
        }


    }

    private void sendMsgAllclient(String msg, SocketChannel socketChannel) {
        System.out.println("服务端开始转发这个消息,当前线程:"+Thread.currentThread().getName());
        for(SelectionKey skey : selector.keys()){

            Channel channel=  skey.channel();

            if(channel instanceof SocketChannel && channel!=socketChannel){
                ByteBuffer buffer=ByteBuffer.wrap(msg.getBytes());
                try {
                    ((SocketChannel) channel).write(buffer);
                } catch (IOException e) {
                    System.out.println("为啥没有收到");
                    e.printStackTrace();
                }
            }


        }

    }

    public static void main(String[] args) {

        Server server=new Server();
        server.connect();

    }


}