关于java:Netty-入门一BIO模型

1 概要

  1. 本文次要探讨BIO模型下,客户端和服务端如何进行交互;
  2. 同时遗留一个问题,临时无解,待当前解决,如果有大神能指点迷津,不胜感激。

2 原理

BIO 顾名思义,Block IO;一旦数据没有筹备实现, 那么就会阻塞;期待数据筹备实现,才会往下执行。
所以 socket的连贯、读、写都会阻塞住。

2.2 长处

在晚期,这种模型也是很好用的。

2.3 毛病

BIO模式下,为了减少服务端的并发, 一个客户端申请往往单开一个线程,而不是占用服务端的主线程。即使是这种状况,服务端的并发量也是顾此失彼,因为一旦客户端不发送音讯了,服务端的一个线程也是阻塞,而不是敞开;也占用资源。

3 具体实现

3.0 代码实现逻辑

客户端发申请,服务端接管申请;服务端接管申请后,在发给客户端一个响应申请;以此往返;

3.1 应用原生的InputStream

3.1.1 Server

public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(8899)) {
            Socket accept = serverSocket.accept();
            while (true) {
                System.out.println("服务端 收到客户端的申请地址:" + accept.getInetAddress());
                while (Objects.nonNull(accept)) {
                    System.out.println(111);
                    InputStream in = accept.getInputStream();
                    byte[] bytes = new byte[1024];
                    int length = 0;
                    while ((length = in.read(bytes)) != -1) {
                        System.out.println("msg from client : " + new String(bytes, 0, length));
                    }
                    System.out.println(" server read msg over");
                    OutputStream outputStream = accept.getOutputStream();
                    String msg = "hello client, I am from Server";
                    outputStream.write(msg.getBytes(StandardCharsets.UTF_8));
                    outputStream.flush();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

3.1.2 Client

public static void main(String[] args) {
        try (Socket socket = new Socket("localhost", 8899)) {
            while (true) {
                OutputStream ois = socket.getOutputStream();
                String hello = "hello server ,I am from Client;";
                ois.write(hello.getBytes(StandardCharsets.UTF_8));
                ois.flush();
                System.out.println(" client write msg over");
                Thread.sleep(666);
                InputStream inputStream = socket.getInputStream();
                byte[] bytes = new byte[1024];
                int length = 0;
                while ((length = inputStream.read(bytes)) != -1) {
                    System.out.println("msg from server: " + new String(bytes, 0, length));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

3.1.3 论断

这种计划,会阻塞;通过打印堆栈信息能够看出,都是卡在socketRead0()办法;即调用inputstream.read(bytes)的时候卡住;
即始终获取不到内容,所以始终卡主;
纳闷点?

  1. 那应该通信几次再卡住才是,而不是一启动就卡主吧?
  2. 以后是找到了起因。但没找到解决办法;
  3. 猜想:以后是不是客服端和服务端共用一个socket,只有有一个写、一个读?

3.2 将InputStream 批改成DataInputStream

3.2.1 Server

    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(8899)) {
            Socket accept = serverSocket.accept();
            while (true) {
                System.out.println("以后连贯服务器的客户端地址:" + accept.getInetAddress());
                DataInputStream dis = new DataInputStream(accept.getInputStream());
                String clientMsg = dis.readUTF();
                System.out.println("msg from client:" + clientMsg);
                DataOutputStream dos = new DataOutputStream(accept.getOutputStream());
                dos.writeUTF("hello client , I am from server ,msg received + " + clientMsg);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

3.2.2 Client

    public static void main(String[] args) {
        try (Socket socket = new Socket("localhost", 8899)) {
            DataInputStream dis = new DataInputStream(socket.getInputStream());
            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
            while(true) {
                String msg = " I am from client";
                dos.writeUTF(msg);
                String s = dis.readUTF();
                System.out.println("msg from server: "+ s);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

3.2.3

不会有阻塞;很奇怪;单方信息打印很通顺;

3.3 应用telnet 作为客户端进行发送音讯

  1. 应用InputStream,如果没有音讯,会卡在socketRead0();然而telnet客户端一旦输出内容, 就会立刻往下走;
  2. 但应用DataInputStream会卡主,telnet输出音讯 也会卡在socketRead0()办法;

3.4 论断

暂无论断;
待问题解决

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理