BIO的工作流程

本文涉及的产品
网络型负载均衡 NLB,每月750个小时 15LCU
全球加速 GA,每月750个小时 15CU
私网连接 PrivateLink,5万GB流量 1.5万小时实例时长
简介: BIO(Blocking I/O)工作流程是指在进行输入输出操作时,线程会一直阻塞直到操作完成。具体流程包括:客户端发起请求,服务器接收后开始处理,期间服务器线程处于等待状态,直至数据准备完毕,响应返回给客户端,线程才继续执行其他任务。
  1. 服务器端启动监听

    • 创建ServerSocket对象:在BIO(Blocking I/O)模型的服务器端,首先需要创建一个ServerSocket对象。这个对象用于监听指定端口上的客户端连接请求。例如,在Java中可以通过ServerSocket serverSocket = new ServerSocket(portNumber);来创建一个监听特定端口(portNumber)的ServerSocket。这一步相当于在服务器上打开了一个“门”,等待客户端来“敲门”。
    • 进入阻塞状态等待连接:服务器启动后,调用ServerSocketaccept方法来等待客户端的连接。这是一个阻塞操作,意味着服务器线程会在这里暂停执行,直到有客户端连接请求到达。例如,Socket socket = serverSocket.accept();这行代码会使服务器线程进入阻塞状态,直到有一个新的客户端成功连接到服务器。
  2. 客户端连接建立

    • 客户端发起连接请求:在客户端,需要创建一个Socket对象并指定服务器的IP地址和端口号来发起连接请求。例如,在Java中可以使用Socket clientSocket = new Socket(serverIP, serverPort);来建立与服务器的连接。当客户端执行这个操作时,它会向服务器发送一个连接请求。
    • 服务器接受连接并返回Socket对象:当服务器的accept方法检测到客户端的连接请求后,它会接受这个请求,并返回一个与该客户端通信的Socket对象。这个Socket对象代表了服务器和客户端之间的通信通道,双方可以通过这个通道进行数据传输。
  3. 数据传输阶段

    • 获取输入输出流:在服务器端和客户端都可以通过Socket对象获取对应的输入流(InputStream)和输出流(OutputStream)。例如,在服务器端可以使用InputStream inputStream = socket.getInputStream();来获取从客户端读取数据的输入流,使用OutputStream outputStream = socket.getOutputStream();来获取向客户端发送数据的输出流。
    • 数据读写操作(阻塞过程)
      • 读数据:当服务器从输入流读取客户端发送的数据时,调用read方法会导致线程阻塞。例如,byte[] buffer = new byte[1024]; int length = inputStream.read(buffer);这行代码会使服务器线程阻塞,直到客户端发送了足够的数据(最多读取buffer长度的数据)或者客户端关闭了连接。读取到的数据存储在buffer数组中,length表示实际读取到的字节数。
      • 写数据:当服务器向客户端发送数据时,通过输出流的write方法。例如,String message = "Hello, client!"; outputStream.write(message.getBytes());,这个操作会将字符串转换为字节数组并发送给客户端。如果网络或客户端接收缓冲区等原因导致数据不能立即发送出去,write操作也可能会阻塞,直到数据成功发送或者出现异常。
  4. 连接关闭阶段

    • 客户端或服务器主动关闭连接:当数据传输完成后,客户端或服务器可以主动关闭连接。在服务器端可以使用socket.close();来关闭与客户端的连接,在客户端也可以使用相同的方式关闭连接。关闭连接后,相关的资源(如套接字、输入输出流等)会被释放。
    • 清理资源:除了关闭Socket对象外,服务器端还需要关闭ServerSocket对象来释放监听端口等资源。例如,serverSocket.close();,这一步通常在服务器程序结束或者不再需要监听该端口时执行,以确保系统资源的合理利用。

BIO的整个工作流程是一种简单直接的同步阻塞式的通信方式。在这个过程中,每个客户端连接通常需要一个单独的线程来处理,因为线程在进行I/O操作(如acceptreadwrite)时会被阻塞,无法同时处理其他客户端的请求。这种方式在连接数较少的情况下可以正常工作,但在高并发场景下可能会导致线程资源的大量消耗和性能下降。

相关文章
|
8月前
|
Java
如何理解网络阻塞 I/O:BIO
如何理解网络阻塞 I/O:BIO
107 3
|
8月前
|
存储 Linux 调度
io复用之epoll核心源码剖析
epoll底层实现中有两个关键的数据结构,一个是eventpoll另一个是epitem,其中eventpoll中有两个成员变量分别是rbr和rdlist,前者指向一颗红黑树的根,后者指向双向链表的头。而epitem则是红黑树节点和双向链表节点的综合体,也就是说epitem即可作为树的节点,又可以作为链表的节点,并且epitem中包含着用户注册的事件。当用户调用epoll_create()时,会创建eventpoll对象(包含一个红黑树和一个双链表);
131 0
io复用之epoll核心源码剖析
|
8月前
|
存储 网络协议 Java
深入理解Linux网络——内核与用户进程协作之同步阻塞方案(BIO)
在上一部分中讲述了网络包是如何从网卡送到协议栈的(详见深入理解Linux网络——内核是如何接收到网络包的),接下来内核还有一项重要的工作,就是在协议栈接收处理完输入包后要通知到用户进程,如何用户进程接收到并处理这些数据。
|
2月前
|
网络协议 Dubbo Java
一文搞懂NIO、AIO、BIO的核心区别(建议收藏)
本文详细解析了NIO、AIO、BIO的核心区别,NIO的三个核心概念,以及NIO在Java框架中的应用等。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
一文搞懂NIO、AIO、BIO的核心区别(建议收藏)
|
3月前
|
Java Linux 应用服务中间件
【编程进阶知识】高并发场景下Bio与Nio的比较及原理示意图
本文介绍了在Linux系统上使用Tomcat部署Java应用程序时,BIO(阻塞I/O)和NIO(非阻塞I/O)在网络编程中的实现和性能差异。BIO采用传统的线程模型,每个连接请求都会创建一个新线程进行处理,导致在高并发场景下存在严重的性能瓶颈,如阻塞等待和线程创建开销大等问题。而NIO则通过事件驱动机制,利用事件注册、事件轮询器和事件通知,实现了更高效的连接管理和数据传输,避免了阻塞和多级数据复制,显著提升了系统的并发处理能力。
79 0
|
6月前
|
安全 Go 调度
深入理解Go语言并发模型:Goroutines与Channels的协同工作
在Go语言的世界里,并发不再是遥不可及的复杂概念,而是通过其独特的并发模型——Goroutines与Channels,变得既强大又易于管理。本文旨在深入探讨Goroutines的轻量级线程特性,以及它们如何通过Channels这一独特的通信机制实现高效、安全的并发执行。我们将从基础概念出发,逐步解析Goroutines的创建、调度,以及如何通过Channels优雅地解决并发编程中的常见问题,如数据竞争、死锁等,最终揭示Go语言并发模型背后的设计哲学与实际应用中的最佳实践。
|
8月前
|
网络协议 前端开发 Java
Netty Review - 核心组件扫盲
Netty Review - 核心组件扫盲
103 0
|
JSON 网络协议 关系型数据库
计网 - 网络 I/O 模型:BIO、NIO 和 AIO 有什么区别?
计网 - 网络 I/O 模型:BIO、NIO 和 AIO 有什么区别?
120 0
|
Java 开发者
BIO 处理模型 | 学习笔记
快速学习 BIO 处理模型
117 0
BIO 处理模型 | 学习笔记