(三)谈谈 IO 模型(Socket 编程篇)
ztj100 2025-07-08 00:26 2 浏览 0 评论
快过年啦,估计很多朋友已在摸鱼的路上。而我为了兄弟们年后的追逐,却在苦苦寻觅、规划,导致文章更新晚了些,各位猿粉谅解。
上期分享,我们结合新春送祝福的场景,通过一坨坨的代码让 BIO、NIO 编程过程呈现的淋漓尽致。
本期分享,通过画几张图,再聊 IO 之 Socket 编程的哪些事儿(小猿舞剑,上期意在代码,这期意在图)。
Socket 翻译为插口、槽,名字很有意义,一旦插入网线进行连接,我们的代码便能够通讯。
如图示意,每个 Socket 都包含两条线,也就是两个流(输入流和输出流)。其实建立网络连接就类似电话系统,一端给另一端打电话(port 就像电话号码),而且一直在监听是不是通了,是不是说话啦。
了解过网络底层协议的都知道,通过使用 Socket,使得开发变得简单了很多,因为 Socket 隐藏了大量的网络开发的细节。其实,对于 Java 程序而言,网络的 IO 就像操作顺序文件的 IO 一样。
如上图示意,Socket 编程模型,倒是不复杂,我们拆开去说。
服务端编程步骤,其实图说的已经很清晰,再絮叨两句。
第一步:创建 ServerSocket 对象;
第二步:接受来自客户端的连接请求并返回 Socket;
第三步:从 Socket 获取输入流/输出流;
第三步:根据数据类型将原始输入流/输出流封装为高级流(可选);
第四步:从流中接收/发送消息;
第五步:释放资源。
客户端与服务端编程步骤差不多,也不复杂。
客户端编程步骤图中也说的很清楚了,不过还是要简单归纳一下。
第一步:创建 Socket;
第二步:从连接的 Socket 获取输入流和输出流;
第三步:根据数据类型将原始输入流/输出流封装为高级流(可选);
第四步:从流中接收/发送消息;
第五步:释放资源。
Socket 编程模型总体来说很简单,所以稍微花点功夫,轻轻松松就能照猫画虎撸出能聊天的程序。
接下来我们再画几张图,一起看看 Socket 编程的演进。
如图所示,服务端首先通过 accept() 方法接受客户端的链接,然后创建线程进行处理客户端的请求,最后把响应发给客户端。这种模型坊间称之为传统 BIO 编程模型图。
聪明的你们会发现,这种模型,如果在客户端访问过多的情况下,服务端需要频繁的启动、销毁线程,那么势必会有性能上的开销;另外,线程数过多,也有可能会拖垮服务器,于是就引入了线程池进行改进。
如上图所示,服务端接收到请求之后,封装成 Task 对象,然后交给线程池去执行任务,最后给客户端响应。
通过引入线程池,来管理工作线程的数量,进而避免频繁创建、销毁线程带来的开销,在实际研发中若是并发量较小的应用,这种设计已经足矣,这种模型在坊间称为伪异步 IO 编程模型图。
但是,这种模型,恰恰由于线程池限制了线程的数量,在高并发场景下,请求超过线程池的最大数量时,那么就只能等待,直到线程池中的有空闲的线程才可以被复用。那么,在网络较差、传输较大文件时,是不是就出现了链接超时?!
这或许就是 BIO(同步阻塞) 的劣势吧,那该怎么办呢?于是就有了 NIO 编程模型。
如图示意,NIO 利用了单线程管理一个Selector,而一个Selector管理多个 SocketChannel,也就是管理多个连接,那么就不用为每个连接都创建一个线程,可以有效避免高并发情况下,频繁线程切换等带来的问题。
举个贴近生活的场景,加深一下理解。当下猪肉的行情着实不错,不妨就举个养猪场的栗子。
养猪场有个看护猪圈的人,他每天要做的事儿,就是不停的检查猪圈,如果有猪生病、有猪生仔、有猪跑出去等等,他就把相应的情况记录下来,如果猪场的老板想知道具体情况,只需要问看护猪圈的那个人就行啦。
容我抽象一下,看护猪圈的人就相当于 Selector,每个猪圈就相当于 SocketChannel,而猪场的老板就相当于线程Thread,他可以通过一个Selector管理多个 SocketChannel,进而服务多个 Socket。
好了,今天就扯这么多,没有引入新知识点,一方面在于把前期的知识点系统的串一串;重点是为了,给找我请教的热情粉丝,一个交代,后续有时间会把 Socket 往深里挖一挖,请大家期待。
相关推荐
- Java网络编程(JAVA网络编程技术)
-
网络编程三要素1.IP地址:表示设备在网络中的地址,是网络中设备的唯一标识2.端口号:应用程序在设备中唯一的标识3.协议:连接和数据在网络中传输的规则。InetAddress类Java中也有一个...
- 字节Java全能手册火了!多线程/网络/性能调优/框架啥都有
-
前言在这个技术不断更新的年代,跟不上时代变化的速度就会被刷掉,特别是咱们程序员这一群体,技术不断更新的同时也要同时进步,不然长江后浪推前浪,前浪......一个程序员从一个什么都不懂的小白在学到有一定...
- 一分钟了解java网络编程(java基础网络编程)
-
一、OSI七层网络模型应用层:Http协议、电子邮件传输、文件服务器等;表示层:数据转换,解决不同系统的兼容问题(跨语言);会话层:建立与应用程序的会话连接;传输层:提供了端口号和传输协议(TPC/U...
- Java编程-高并发情况下接口性能优化实践-提升吞吐量TPS
-
记得前段时间工作中接到一个任务是优化一个下单接口的性能提高接口的吞吐量TPS,前期通过arthas工具跟踪接口的具体方法调用链路及耗时,发现了影响此接口的性能瓶颈主要是加锁的方式,后来变更了锁的方式...
- socket 断线重连和心跳机制如何实现?
-
一、socket概念1.套接字(socket)是网络通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,...
- 迅速了解-Java网络编程(java基础网络编程)
-
Java网络编程在JavaSE阶段,我们学习了I/O流,既然I/O流如此强大,那么能否跨越不同的主机进行I/O操作呢?这就要提到Java的网络编程了。...
- Java网络编程详解(java 网络编程)
-
网络编程基础知识最!最!最!重要网络编程基础概念网络编程不等于网站编程,网络编程即使用套接字(socket)来达到各进程间的通信,现在一般称为TCP/IP编程;网络编程分为服务端和客户端。服务端就相当...
- 「开源推荐」高性能网络通信框架 HP-Socket v5.7.2
-
简介HP-Socket是一套通用的高性能TCP/UDP/HTTP通信框架,包含服务端组件、客户端组件和Agent组件,广泛适用于各种不同应用场景的TCP/UDP/HTTP通信系统,提供C/...
- Java网络编程从入门到精通:打造属于你的网络世界
-
Java网络编程从入门到精通:打造属于你的网络世界在当今这个信息爆炸的时代,网络编程已经成为程序员必不可少的一项技能。而Java作为一种功能强大且广泛使用的编程语言,在网络编程领域也有着举足轻重的地位...
- 5分钟读懂C#中TcpClient、TcpListener和Socket三个类的角色
-
一、核心功能与定位1.Socket类:底层通信的基石-位于System.Net.Sockets命名空间,提供对网络协议栈的直接操作,支持TCP、UDP等多种协议。-手动管理连接细节:需...
- (三)谈谈 IO 模型(Socket 编程篇)
-
快过年啦,估计很多朋友已在摸鱼的路上。而我为了兄弟们年后的追逐,却在苦苦寻觅、规划,导致文章更新晚了些,各位猿粉谅解。上期分享,我们结合新春送祝福的场景,通过一坨坨的代码让BIO、NIO编程过程呈...
- 大数据编程入门:Java网络编程(大数据 编程)
-
如果想要编写出一个可以运行在多个设备上的程序,应该怎么做呢?答案是网络编程,今天小编将为大家带来大数据编程入门:Java网络编程。一、网络编程概念网络编程是指编写在通过网络连接的多个设备(计算机)上运...
- 基于JAVA的社交聊天室(java聊天设计与实现)
-
基于Java的社交聊天室一、前言随着互联网技术的迅速发展,实时通信和在线社交已成为人们日常生活的重要组成部分。基于Java的社交聊天室系统,凭借其跨平台、高性能和安全性等特点,为用户提供了一个集中、开...
- java-socket长连接demo体验(java socket长连接)
-
作者:DavidDing来源:https://zhuanlan.zhihu.com/p/56135195一、前言最近公司在预研设备app端与服务端的交互方案,主要方案有:服务端和app端通过阿里i...
- JAVA数据库编程(java数据库编程指南)
-
预计更新###第一节:什么是JAVA-JAVA的背景和历史-JAVA的特点和应用领域-如何安装和配置JAVA开发环境###第二节:JAVA基础语法-JAVA的基本数据类型和变量-运算符和...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)