I/O-BIO

作者: 麦大大吃不胖 | 来源:发表于2020-11-28 08:32 被阅读0次

by shihang.mai

1. BIO:ScoketIO

阻塞IO模型,举例:SocketIOPropertites

服务端

public class SocketIOPropertites {



    //server socket listen property:
    private static final int RECEIVE_BUFFER = 10;
    private static final int SO_TIMEOUT = 0;
    private static final boolean REUSE_ADDR = false;
    private static final int BACK_LOG = 2;
    //client socket listen property on server endpoint:
    private static final boolean CLI_KEEPALIVE = false;
    private static final boolean CLI_OOB = false;
    private static final int CLI_REC_BUF = 20;
    private static final boolean CLI_REUSE_ADDR = false;
    private static final int CLI_SEND_BUF = 20;
    private static final boolean CLI_LINGER = true;
    private static final int CLI_LINGER_N = 0;
    private static final int CLI_TIMEOUT = 0;
    private static final boolean CLI_NO_DELAY = false;
/*
    StandardSocketOptions.TCP_NODELAY
    StandardSocketOptions.SO_KEEPALIVE
    StandardSocketOptions.SO_LINGER
    StandardSocketOptions.SO_RCVBUF
    StandardSocketOptions.SO_SNDBUF
    StandardSocketOptions.SO_REUSEADDR
 */


    public static void main(String[] args) {

        ServerSocket server = null;
        try {
            server = new ServerSocket();
            server.bind(new InetSocketAddress( 9090), BACK_LOG);
            server.setReceiveBufferSize(RECEIVE_BUFFER);
            server.setReuseAddress(REUSE_ADDR);
            server.setSoTimeout(SO_TIMEOUT);

        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("server up use 9090!");
        while (true) {
            try {
                System.in.read();  //分水岭:

                Socket client = server.accept();
                System.out.println("client port: " + client.getPort());

                client.setKeepAlive(CLI_KEEPALIVE);
                client.setOOBInline(CLI_OOB);
                client.setReceiveBufferSize(CLI_REC_BUF);
                client.setReuseAddress(CLI_REUSE_ADDR);
                client.setSendBufferSize(CLI_SEND_BUF);
                client.setSoLinger(CLI_LINGER, CLI_LINGER_N);
                client.setSoTimeout(CLI_TIMEOUT);
                client.setTcpNoDelay(CLI_NO_DELAY);

                new Thread(
                        () -> {
                            while (true) {
                                try {
                                    InputStream in = client.getInputStream();
                                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                                    char[] data = new char[1024];
                                    int num = reader.read(data);

                                    if (num > 0) {
                                        System.out.println("client read some data is :" + num + " val :" + new String(data, 0, num));
                                    } else if (num == 0) {
                                        System.out.println("client readed nothing!");
                                        continue;
                                    } else {
                                        System.out.println("client readed -1...");
                                        client.close();
                                        break;
                                    }

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

            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    server.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

客户端

public class SocketClient {

    public static void main(String[] args) {

        try {
            Socket client = new Socket("192.168.3.24",9090);

            client.setSendBufferSize(20);
            client.setTcpNoDelay(false);
            client.setOOBInline(false);
            OutputStream out = client.getOutputStream();

            InputStream in = System.in;
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));

            while(true){
                String line = reader.readLine();
                if(line != null ){
                    byte[] bb = line.getBytes();
                    for (byte b : bb) {
                        out.write(b);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2. 过程详解

BIO图解

BIO现象过程

  1. 只启动服务端(ServerSocket没accept)。 出现一个fd代表listen
  2. 再启动客户端连接服务端,不发消息。客户端和服务端进行3次握手,服务端会出现一个另外fd代表socket连接,但是还没分配进程处理
  3. 客户端发送消息,socket连接的rev-q有数据
  4. 服务端accept,socket连接已分配进程处理,并打印了客户端发来的消息
属性 位置 备注
BACK_LOG 服务端 可连接客户端的个数。当超出个数时,用netstat -natp查看进程时,发现有SYN_RECV状态,即3次握手未成功建立。
TcpNoDelay 客户端 设置为fasle时,表明打开优化。一次性发送大于设置SendBufferSize的值,会一次性发送所有的消息,并不会受SendBufferSize约束。
CLI_KEEPALIVE 服务端 服务端-客户端自动保持心跳
BIO

系统调用过程

  1. 调用socket()返回一个fd
  2. 调用bind(fd,9090),将fd和端口绑定起来
  3. 调用listen(),监听端口
  4. 调用accept(),会产生一个新fd而且会标注为blocking的
  5. 调用recv(新fd),也是标注为blocking的

3. BIO弊端

它accept和receive都是阻塞的.当我们accept后,开启线程去处理,每个连接均需要调用内核的clone()去创建线程

BIO弊端

相关文章

  • I/O-BIO

    BIO by shihang.mai BIO:ScoketIO 阻塞IO模型,举例:SocketIOPropert...

  • āiáiǎiài

    买了新的唇膏 水蜜桃配仙草 楼上的邻居 闹钟响第四遍的时候 发觉是爱情的马脚 偷笑着我没睡着 什么过不去还舍不得忘...

  • I f I f I f I f I f I f I f I f

    文/雅雅 以思考,进化时代。 2018年的第一篇文章,我一直思考书写的使命是什么? 对于我,对于我以外的看他的你。...

  • 【I原创I】I花园

    早些年的奇闻异事 偏偏不生杂草 把春天还给篝火 你祛毒 你神性 你感动于 光合作用的前所未有

  • 面试细节: i = i++和 i = ++i

    作者:默辩 来源:https://blog.csdn.net/qq_44377709/article/detail...

  • i++ ++i

    区分变量的值与表达式的值 变量名:也称标识符,一个 JavaScript 标识符必须以字母、下划线(_)或者美元符...

  • i++ ++i

    区分变量的值与表达式的值 i++ :表达式取原值,j但i的值是加1或减1之后的值++i :表达式和i的值都是加1或...

  • i++ ++i

    区分变量的值与表达式的值 i++ :表达式取原值,j但i的值是加1或减1之后的值++i :表达式和i的值都是加1或...

  • I am I

    老子在《道德经》中说:“知人者智,自知者明。许多人没活明白,大致原因是不知道自己是什么样的人,喜欢什么,讨厌什么。...

  • I AM I

    今天在阅读简书文章的时候,看到下面的一段话。 突然间想到好朋友曾经也对我说过我有点好高骛远,不够踏实,再一次的意识...

网友评论

      本文标题:I/O-BIO

      本文链接:https://www.haomeiwen.com/subject/ynhoiktx.html