网络通信IO模型-BIO

news2025/1/9 16:54:30

承接上文网络通信IO模型上

BIO的Java代码

服务端创建一个ServerSocket,绑定了端口号8090,目的是让客户端和服务端建立连接后进行通信,然后进入死循环,死循环里面会调用server.accept得到一个socket客户端,打印客户端的端口号,然后启动一个线程,为什么要启动一个线程?

因为accpet会阻塞,如果因为没有客户端建立连接,就没有返回值,会一直阻塞,只有客户端建立连接,才能从阻塞变成返回,然后再读取客户端发送过来的数据,读取输入流并打印用户发送的数据,读取的话,也有可能变成阻塞状态,如果客户端一直不发送数据过来,服务器端就会一直阻塞,所以要把客户端读取的过程放到另外一个线程里面去做。

通过strace命令追踪进程情况

strace -ff -o out java TestSocket
  • ff 代表追踪这个程序所有的线程

通过strace命令追踪java程序有多少个线程,每个线程对内核产生哪些系统调用,都会记录下来。

启动该程序,首先会打印

表示第一步创建一个ServerSocket,绑定了8090端口,然后进入阻塞状态,直到有客户端建立连接。

这时多了以out开头、数值结尾的8个文件,代表8个线程。

当有一个客户端连接的时候,会new一个新线程,就变成9个out文件了。

一个java程序刚启动的时候,它自身就是多线程的,有些线程负责gc回收,有些线程负责监控客户端建立的socket连接等。

上图中的主线程是8211,

查看out.8211就可以看到java程序在运行时和内核交互的整个过程。

每一行最前面代表系统调用的内核函数名称,接着是入参,最后是返回值。

先看这个文件的最后一行,accept阻塞在这里了,一直在等待客户端的连接。

首先系统调用socket方法得到一个文件描述符3即对应ServerSocket,将3绑定到8090端口上,绑定完之后,下面listen表示开始监听3,其实是在监听8090这个端口。

从阻塞到不阻塞的过程是怎样的?

启动TestSocket程序,进程编号是8211,主线程编号也是8211,监听端口是8090,目标地址可以是任何地址和任何端口。

用nc模拟一个客户端建立连接

nc localhost 8090

nc(net connection或net cat)就想象成一个网络通信的客户端,它能帮你完成tcp的三次握手。

TestSocket程序就会打印一个客户端连接进来了,

表示客户端申请了一个随机端口号连接到了服务端8090,

刚才accept 3 阻塞在这里了,一个客户端连接进来之后,就会立刻返回一个代表客户端连接的文件描述符5,并且绑定了客户端端口号,

现在多了一个连接状态,目标程序是本地服务(127.0.0.1)的8090端口,来自于本地的59033这个客户端程序,

59033正好对应nc进程。

TestSocket程序从开始只有一个文件描述符3,然后一个客户端建立了连接得到了文件描述符5,然后Java主线程启动一个子线程读取文件描述符5.

如何启动一个新的线程?

调用clone这个内核的系统调用创建了一个新的线程8281。

java的线程其实就是调用内核的系统调用clone,然后得到一个8281线程,这个线程同属于最开始的进程id 8211,

8211代表一个线程组。

此时又多了一个8281的线程文件,查看该文件

调用了内核的recv方法,文件描述符5是在主线程产生的一个客户端socket连接,用另外一个线程去读文件描述符5。

主线程继续accpet。

每多一个连接,就多了一个线程,如果有一万个连接,就会有一万个线程。

整体过程

先调用socket返回fd 3,将fd 3绑定8090端口,然后监听8090端口。

while死循环,先accept接收客户端的连接,如果没有连接就一直阻塞,如果有连接,则读取连接,如果客户端一直没有发送数据过来,就会一直阻塞,所以为了不影响主线程接收连接,再创建一个新的线程,用于读取每个客户端发送过来的数据。

这是最古老的网络IO模型BIO。

一个线程对应一个连接,优势是可以接受很多连接。

弊端:如果进程特别多或线程特别多的时候,就会造成内存的浪费,cpu调度也会消耗了更多cpu的时间片。

BIO中有2个方法是阻塞(BLOCKING)的,一个是主线程的accept,另一个是recv或read这2个方法。

这2个系统调用会阻塞,所以不能把都有可能阻塞的操作放到一个线程里 ,否则一个阻塞就会干预到另外一个阻塞,所以解决BIO模型的弊端 ,只需要非阻塞(NON BLOCKING)就可以了,非阻塞网络模型就是NIO了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/580928.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【PyQt5】指示灯显示

【PyQt5】指示灯显示 1、背景2、代码示例3、QtDesigner绘制 1、背景 利用Qt5写工业控制软件交互界面的时候,经常需要在界面上有指示灯功能。 例如下面的明暗表示串行端口的连接和断开。 我们本质是用Qt5的label文本标签来实现的,即通过设置标签的样式表…

115.删除有序数组中的重复项 removeDuplicatesFromSortedArray

文章目录 题目描述解题思路代码详解运行截图 题目描述 题目链接 给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元…

C# | 凸包算法之Jarvis,寻找一组点的边界/轮廓

C#实现凸包算法之Jarvis 文章目录 C#实现凸包算法之Jarvis前言示例代码实现思路测试结果结束语 前言 这篇关于凸包算法的文章,本文使用C#和Jarvis算法来实现凸包算法。 首先消除两个最基本的问题: 什么是凸包呢? 凸包是一个包围一组点的凸多…

驱动LSM6DS3TR-C实现高效运动检测与数据采集(1)----获取ID

概述 本文将介绍如何驱动和利用LSM6DS3TR-C传感器,实现精确的运动感应功能。LSM6DS3TR-C是一款先进的6轴惯性测量单元(IMU),集成了三轴加速度计和三轴陀螺仪,可用于测量和检测设备的加速度、姿态和运动。 本文将提供L…

车载软件架构 —— 闲聊几句AUTOSAR OS(二)

我是穿拖鞋的汉子,魔都中坚持长期主义的工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 在最艰难的时候,自己就别去幻想太远的将来,只要鼓励自己过好今天就行了! 这世间有太多的猝不及防,有些东西根本不配占有自己的情绪,人生就是一场体验,…

牛客HJ43迷宫问题 - 创建智能体通过策略自己找路

文章目录 问题描述思路代码C 问题描述 描述 定义一个二维数组 N*M ,如 5 5 数组下所示: int maze[5][5] { 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫,其中的1表示墙壁&#xff0…

SPA首屏加载速度慢的怎么解决?

SPA首屏加载速度慢的怎么解决? 加载慢的原因 网络延时问题资源文件体积是否过大资源是否重复发送请求去加载了加载脚本的时候,渲染内容堵塞了 解决方案 1.减小入口文件体积 常用的手段是路由懒加载,把不同路由对应的组件分割成不同的代码…

如何在华为OD机试中获得满分?Java实现【水仙花数】一文详解!

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Java华为OD机试真题(2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述4. Java算法源码5. 测试6.解题思路1. 题目描述 所谓水仙花数,是指一个…

LeetCode高频算法刷题记录10

文章目录 1. 旋转图像【中等】1.1 题目描述1.2 解题思路1.3 代码实现 2. 组合总和【中等】2.1 题目描述2.2 解题思路2.3 代码实现 3. 回文链表【简单】3.1 题目描述3.2 解题思路3.3 代码实现 4. 字符串解码【中等】4.1 题目描述4.2 解题思路4.3 代码实现 5. 多数元素【简单】5.…

高压功率放大器ATA4014VS高压功率放大器HSA42014

高压功率放大器ATA4014VS高压功率放大器HSA42014 一、企业背景: Aigtek是一家来自中国的专业从事测量仪器研发、生产和销售的高科技企业。公司主要研发和生产功率放大器、功率放大器模块、功率信号源、计量校准源等产品。核心团队主要是来自西安交通大学及西北工业大…

ERP系统介绍

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、ERP系统概述?1.什么是ERP2.主流ERP系统介绍3.用友ERP4.部署用友ERP畅捷通T6软件系统环境要求4.用友ERP畅捷通T6软件用户管理4.用友ERP畅捷通T6软…

简单的UDP网络程序

目录 准备工作 makefile udpServer.hpp udpServer.cc 细节1 服务端部署 创建套接字 接口认识1 socket 协议家族 绑定套接字 认识接口2 bind sockaddr_in结构体类型 细节2 bzero inet_addr 服务器启动(初启动) udpServer.hpp udpServer.cc 细节3 本地回环通…

跑通NeRF-SLAM代码记录

前言 Install 原文章github链接 下载代码 git clone https://github.com/ToniRV/NeRF-SLAM.git --recurse-submodules git submodule update --init --recursive因为有相关依赖,所以尽量使用命令下载代码。 2. 新建nerf-slam环境,github上也没提到p…

从sftp下载大文件到浏览器

从sftp下载大文件到浏览器 问题方案相关依赖包相关代码片段(后端)文件信息缓存工具类-FileChunkCache文件信息对象-FileDetailsftp传输进度监控-FileProgressMonitor切片工具类-ChunkService文件下载服务-AsyncDownloadService 问题 近期遇到直接使用sf…

Dubbo与SpringBoot整合

1.注意starter版本适配 2.服务提供者 创建Maven项目 boot-user-service-provider 服务提供者 2.1.通用模块依旧照用 2.2.POM <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</a…

如何在华为OD机试中获得满分?Java实现【IPv4地址转换成整数】一文详解!

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Java华为OD机试真题(2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述4. Java算法源码5. 测试6.解题思路1. 题目描述 存在一种虚拟 IPv4<

本地创建的项目托管到git

本地创建的项目托管到git 这里的情况是本地先通过命令在电脑上指定文件夹创建好项目后&#xff0c;需要托管到git上&#xff0c;这里以gitee为例 打开gitee&#xff0c;登录滑动到右上方&#xff0b;&#xff0c;点击新建仓库&#xff0c;跳转到新建仓库页面 填写仓库信息&am…

Ubuntu18.04+RTX3060+TensorFlow2.12.0(GPU版)+Cuda11.1+CuDNN8.6.0安装

前情提要 可以跳过 我在Ubuntu18.04上安装了pytorch的相关环境&#xff0c;配置如图。 Ubuntu18.04RTX3060显卡配置pytorch、cuda、cudnn和miniconda_Toblerone_Wind的博客-CSDN博客之前已经安装成功了&#xff0c;也发了篇博客梳理了整套流程如下。ubuntu18.04安装pytorch、c…

回归预测 | MATLAB实现实现FOA-BP果蝇算法优化BP神经网络多变量输入回归预测模型

回归预测 | MATLAB实现实现FOA-BP果蝇算法优化BP神经网络多变量输入回归预测模型 目录 回归预测 | MATLAB实现实现FOA-BP果蝇算法优化BP神经网络多变量输入回归预测模型效果一览基本介绍程序设计参考资料 效果一览 基本介绍 果蝇算法(FOA)优化BP神经网络回归预测,FOA-BP回归预测…

springboot3.0集成nacos2.2.1(一)

本章节内容是没有开启nacos校验方式进行接入 集成环境&#xff1a; java版本&#xff1a;JDK17 springboot版本&#xff1a;3.0.2 创建spring项目&#xff0c;我这里用到的是spring-cloud全家桶 首先是jar包依赖&#xff1a; <properties><maven.compiler.so…