网络I/O编程2 BIO

Posted 健康平安的活着

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络I/O编程2 BIO相关的知识,希望对你有一定的参考价值。

一 BIO

1.1 BIO特点

BIO(blocking i/o): 同步阻塞,务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情就会造成不必要的连接开销。可以通过线程池机制改善。

1.2 BIO的工作流程

1.服务器启动一个ServerSocket
2.客户端启动Socket对服务器进行通信,默认情况下服务器端要对每个客户建立一个线程与之通讯。
3.客户端发出请求后,先咨询服务器是否有线程响应,如果没有则会等待,或者被拒绝。
4.如果有响应,客户端线程会等待请求结束后,再继续执行。

二 BIO实操案例

2.1 需求描述

1.使用BIO模型编写一个服务器端,监听6666端口,当有客户端连接时,就启动一个线程与之通讯。
2.要求使用线程池机制改善,可以连接多个客户端
3.服务器可以接收客户端发送的数据,使用telnet方式做验证。

2.2 上代码

package com.ljf.netty.bio;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @ClassName: BioExample
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2022/05/12 14:25:46
 * @Version: V1.0
 **/
public class BioExample 
    public static void main(String[] args) throws IOException 
        //1.创建一个线程池
        //2.如果有客户端连接,就创建一个线程,与之通讯。
        ExecutorService executorService = Executors.newCachedThreadPool();
        ServerSocket serverSocket = new ServerSocket(6666);
         System.out.println("服务器启动了!!!");
        while (true) 
            System.out.println("等待客户端的连接.....");
            //阻塞监听客户端
            final Socket socket = serverSocket.accept();
            System.out.println("已经连接上一个客户端.....");
            //创建一个新的线程处理连接
            executorService.execute(new Runnable() 
                @Override
                public void run() 
                    handler(socket);
                
            );
        

    
    /**
    * @author liujianfu
    * @description       编写一个handler方法,和客户端进行通讯
    * @date 2022/5/12 14:34
    * @param [socket]
    * @return void
    */
    private static void handler(final Socket socket) 
        try 
            System.out.println("线程信息id="+Thread.currentThread().getId()+" 线程name:"+Thread.currentThread().getName());
            InputStream inputStream = socket.getInputStream();
            byte[] bytes = new byte[1024];
            //循环读取
            while (true) 
                System.out.println("线程信息id="+Thread.currentThread().getId()+" 线程name:"+Thread.currentThread().getName());
                int read=inputStream.read(bytes);
                if (read != -1) 
                    String str = new String(bytes,0,read, Charset.defaultCharset());
                    System.out.println(str);
                
                else
                    break;
                
            
         catch (IOException e) 
            e.printStackTrace();
         finally 
            System.out.println("关闭客户端的连接!!!!");
            try 
                socket.close();
             catch (IOException e) 
                e.printStackTrace();
            
        

    


启动cmd客户端:

输入   telnet  localhost  6666

然后,按住 ctr+] ,进入发送模式

查看结果:

 2.3 不足之处

每个请求都需要创建独立的线程,当并发数较大时,需要创建大量线程来处理连接,系统资源占用较大。

连接建立后,如果当前线程暂时没有数据可读,则线程就阻塞在Read操作上,造成线程资源浪费。

以上是关于网络I/O编程2 BIO的主要内容,如果未能解决你的问题,请参考以下文章

一站式学习Java网络编程 全面理解BIO/NIO/AIO

网络通信之 AIO 和 BIO和 NIO

BIO~~

3. BIO(Blocking I/O)

java BIO/NIO/AIO 学习

java之BIO简介