伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 教育考试 » 文章详细 订阅RssFeed

【java】网络编程之BIO

来源:本站原创 浏览:86次 时间:2022-12-07

BIO(阻塞式输入输出)是指在读取输入数据的时候会一直卡(阻塞)在那里,在socket编程中会导致线程无法处理其他工作,除此之外,服务端等待accept连接也是阻塞式的,所以程序想继续执行需要创建新的线程去处理其他工作。

注意socket连接并不代表连接可以被处理,连接创建后,数据处理是需要线程来工作的,当然一个进程的可连接数也不是无限大的,超过最大连接数(操作系统限制或服务端限制)会导致无法连接。

类似阻塞式的饭店,新客人来了相当于和饭店建立一个socket连接,这只是连接能不能吃饭还要等待服务员给你下单,当然饭店要是满了,新客人是进不去的。更糟糕的是,饭店只有一个服务员一直等着给第一个客人点菜下单,其他客人都不管。客人也存在着类似问题,为了和服务员维持这个连接,一直点菜或思考点什么菜,卡在那里。

----

为了解决上述线程阻塞的问题,只能创建新的线程来完成其他工作,使程序得以继续执行,下面使用两个类(BioServer,BioClient)模拟一下BIO。

public class BioServer {
  private ServerSocket serverSocket;
  public BioServer(int port,int backlog) throws IOException {
    this.serverSocket = new ServerSocket(port,backlog);
  }
  private void start() throws IOException {
    ExecutorService executorService = Executors.newFixedThreadPool(2);
    while (true) {
      Socket socket = serverSocket.accept();
      System.out.println(String.format("a new client connect %s", socket.getPort()));
      executorService.submit(new BioServerHandler(socket));
    }
  }
  public static void main(String[] args) throws IOException {
    new BioServer(6000,3).start();
  }
}
class BioServerHandler implements Runnable {
  private Socket socket;
  public BioServerHandler(Socket socket) {
    this.socket = socket;
  }
  @Override
  public void run() {
    try (BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      PrintWriter pw = new PrintWriter(socket.getOutputStream())) {
      String msg;
      while ((msg = br.readLine()) != null) {
        System.out.println(String.format("server receive:%s", msg));
        pw.println(msg + " | " + new Date());
        pw.flush();
      }
    } catch (IOException e) {...}
  }
}

服务端使用线程池来处理客户端连接,避免accept阻塞当前线程,程序无法继续,而在单个连接的线程处理中,又存在着阻塞式的read,所以线程池中的一个线程只能为一个连接工作,无法复用(除非有连接断开线程释放)。
----
public class BioClient {
  private Socket socket;
  public BioClient(String host,int port) throws IOException {
    this.socket = new Socket(host, port);
  }
  public void start() {
    new Thread(()->{
        try(BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()))){
        String msg;
        while((msg = br.readLine())!=null){
             System.out.println(String.format("client receive %s", msg));
        }
       } catch (IOException e) {...}finally {...}
     }).start();
    System.out.println("client enter msg: ");
    PrintWriter pw;
    while(true){
      try {
        pw = new PrintWriter(socket.getOutputStream());
        pw.println(new Scanner(System.in).next());
        pw.flush();
      } catch (IOException e) {...}
    }
}
  public static void main(String[] args) throws IOException {
     new BioClient("127.0.0.1",6000).start();
  }
}
客户端为了避免阻塞读取数据,创建新线程来处理数据读取工作,在当前线程阻塞式等待系统输入数据。以上就是阻塞式网络编程BIO的demo,主要存在的问题是阻塞导致线程无法复用。


  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net