Java中BIO工作机制

本文详细介绍了Java中的BIO( Blocking I/O)模型,包括其同步阻塞的特点以及在服务器实现中可能遇到的线程开销问题。通过示例展示了如何使用BIO创建服务器端和客户端,以及如何通过线程池来优化资源消耗。同时,提供了使用telnet进行简单测试的效果展示。
摘要由CSDN通过智能技术生成

一、BIO(Blocking I/O)简介

  1. 同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。
  2. Java中的BIO分为两种:
    (1)、传统 BIO:一请求一应答
    (2)、伪异步 IO:通过线程池固定线程的最大数量,防止资源的耗费。
    在这里插入图片描述

BIO:同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中。


二、BIO代码实现

1、Server

/**
 * 1、服务器端启动一个ServerSocket 
 * 2、客户端启动Socket对服务器端进行通信, 默认情况下服务器端需要对每一个客户端建立线程与之通讯
 * 3、客户端发出请求后,先咨询服务器是否有线程响应,如果没有 则会等待,或者被拒绝 
 * 4、如果有响应,客户端会等待请求结束之后,再继续执行
 *
 */
public class BioServer {
	public static void main(String[] args) throws Exception {

		// 使用线程池机制

		// 1、创建一个线程池
		// 2、如果有客户端连接,就创建一个线程与之通讯(单独写一个方法)

		ExecutorService threadPool = Executors.newCachedThreadPool();

		// 创建ServerSocket,监听一个端口
		@SuppressWarnings("resource")
		ServerSocket serverSocket = new ServerSocket(6666);
		System.out.println("服务器端启动了");

		while (true) {
			// 监听,等待客户端连接
			final Socket socket = serverSocket.accept();
			
			// 获取到客户端的ip和port
			InetAddress inetAddress = socket.getInetAddress();
			String address = inetAddress.getHostAddress();
			int port = socket.getPort();
			final String ipAddress = address + ":" + port;
			System.out.println("连接到一个客户端:"+ipAddress);

			// 创建一个线程,与之通讯
			threadPool.execute(new Runnable() {
				public void run() { // 重写run方法
					// 可以和客户端进行通讯
					handle(socket,ipAddress);
				}
			});

		}
	}

	// 编写一个handle方法和客户端进行通讯
	public static void handle(Socket socket,String ipAddress) {

		try {
			byte[] bytes = new byte[1024];
			// 通过socket获得输入流
			InputStream inputStream = socket.getInputStream();

			// 循环读取客户端发送的数据
			while (true) {
				int read = inputStream.read(bytes);
				if (read != -1) {
					System.out.println(ipAddress + "发送的数据为:"
							+ new String(bytes, 0, read)); // 输出数据
				} else {
					break;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			System.out.println("关闭和client的连接");
			try {
				socket.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

2、client

public class BioClient {
	public static void main(String[] args) throws Exception {
		
		Socket socket = new Socket("127.0.0.1",6666);
		OutputStream outputStream = socket.getOutputStream();
		
		String send = "hello world";
		byte[] bytes = send.getBytes();
		outputStream.write(bytes);
		
		socket.close();
		outputStream.close();
	}
}

效果如下:
在这里插入图片描述
3、telnet测试
(1)、连接Server

telnet 127.0.0.1 6666

在这里插入图片描述
(2)、发送字符
在这里插入图片描述
(3)、效果如下
在这里插入图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值