• bio编程示例


    直接干代码,用BIO写一个Server端,然后使用telnet模拟客户端发送数据

    import java.io.IOException;
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class BioServer {
        public static void main(String[] args) throws IOException {
            // 1.创建一个线程池
            ExecutorService executorServices = Executors.newCachedThreadPool();
            // 2. 创建一个ServerSocket服务端
            ServerSocket serverSocket = new ServerSocket(8888);
            System.out.println("服务端启动成功!");
    
            while (true) {
                System.out.println("线程:" + Thread.currentThread().getId() + "-等待客服端连接。。。");
                final Socket socket = serverSocket.accept(); // 如果没有客户端与server端建立连接,这里会一直阻塞
                System.out.println("连接到一个客户端");
                executorServices.submit(() -> bzHandler(socket));
            }
        }
    
        /**
         * 业务方法,与客户端通信
         *
         * @param socket
         */
        public static void bzHandler(Socket socket) {
            try {
                byte[] bytes = new byte[1024];
                // 通过socket获取输入流
                InputStream inputStream = socket.getInputStream();
    
                // 循环读取输入流中的数据
                while (true) {
                    System.out.println("线程:" + Thread.currentThread().getId() + "-等着读取客户端输入流中的内容。。。。");
                    int read = inputStream.read(bytes);  //如果已经建立连接的客户端没有发送数据,这里会一直阻塞
                    if (read != -1) {
                        System.out.println(new String(bytes, 0, read));
                    } else {
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    (1)程序启动,控制台打印如下:

    服务端启动成功!
    线程:1-等待客服端连接。。。

    说明主线程阻塞在accept()这句代码这儿了。。。

    (2)使用telnet建立连接后(注意还没有send数据到服务端),控制台打印如下:

    服务端启动成功!
    线程:1-等待客服端连接。。。
    连接到一个客户端
    线程:1-等待客服端连接。。。
    线程:11-等着读取客户端输入流中的内容。。。。
    连接到一个客户端 : 很容易理解
    线程:11-等着读取客户端输入流中的内容。。。。: 说明创建了一个线程去处理与客户端的连接,同时程序也卡在了 inputStream.read(bytes)这儿,阻塞了!
    线程:1-等待客服端连接。。。: 说明主线程accept一个socket连接之后,在交给子线程处理后,主线程又阻塞在了accept()方法这儿。。。


    (3)客户端发送数据到server端,控制台打印如下:
     
    服务端启动成功!
    线程:1-等待客服端连接。。。
    连接到一个客户端
    线程:1-等待客服端连接。。。
    线程:11-等着读取客户端输入流中的内容。。。。
    zhengqinfeng
    线程:11-等着读取客户端输入流中的内容。。。。

      前面的打印就不说了,

      zhengqinfeng :说明server端接收到了client端发送过来的数据 

      线程:11-等着读取客户端输入流中的内容。。。。  : 说明子线程又阻塞到了read()方法处。。

       

    (4) 再启一个client端 , 控制台打印如下:

    服务端启动成功!
    线程:1-等待客服端连接。。。
    连接到一个客户端
    线程:1-等待客服端连接。。。
    线程:11-等着读取客户端输入流中的内容。。。。
    zhengqinfeng
    线程:11-等着读取客户端输入流中的内容。。。。
    连接到一个客户端
    3线程:1-等待客服端连接。。。
    线程:12-等着读取客户端输入流中的内容。。。。

      又是一个线程去处理新的连接  。。。

    总结: 

    (1)BIO, 同步阻塞,主线程会阻塞,子线程同样也会阻塞。

    (2)每一个客户端连接过来时,server端都会创建一个子线程去与之交互

    补充: telnet发送请求

    (1)telnet 127.0.0.1 8888

    (2) ctrl+]

    (3) send data 

     
     


     
  • 相关阅读:
    Markdown实用教程
    Python三次登陆
    Python猜年龄
    Pycharm用鼠标滚轮控制字体大小
    检测浏览器是否存在某个css或者js的api
    隐式绑定和显式绑定实现一个apply
    promise顺序执行的多种方案
    数据结构栈的定义和使用
    数据以及数据结构是数据处理的起点
    Vue的高阶组件(HOC)使用举例
  • 原文地址:https://www.cnblogs.com/z-qinfeng/p/11946416.html
Copyright © 2020-2023  润新知