快过年啦,估计很多朋友已在摸鱼的路上。而我为了兄弟们年后的追逐,却在苦苦寻觅、规划,导致文章更新晚了些,各位猿粉谅解。

上期分享,我们结合新春送祝福的场景,通过一坨坨的代码让 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 往深里挖一挖,请大家期待。

从 Socket 编程谈谈 IO 模型(三)的更多相关文章

  1. Socket 网络编程和IO模型

    最近做了一个织机数据采集的服务器程序. 结构也非常简单,织机上的嵌入式设备,会通过Tcp 不停的往服务器发送一些即时数据.织机大改有个几十台到几百台不定把 刨去业务,先分析一下网络层的大概情况.每台织 ...

  2. Linux 网络编程(IO模型)

    针对linux 操作系统的5类IO模型,阻塞式.非阻塞式.多路复用.信号驱动和异步IO进行整理,参考<linux网络编程>及相关网络资料. 阻塞模式 在socket编程(如下图)中调用如下 ...

  3. 【并发编程】IO模型

    一.要点回顾 为了更好地了解IO模型,我们需要先回顾下几个概念:同步.异步.阻塞.非阻塞 同步: 一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行.就是在发出一个功能调用时,在没 ...

  4. linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)

      IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...

  5. python网络编程——网络IO模型

    1 网络IO模型介绍 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种:    (1)同步阻塞IO(Blocking IO):即传统的IO模型.    (2)同步非阻塞IO(Non-bl ...

  6. Python socket编程之IO模型介绍(多路复用*)

    1.I/O基础知识 1.1 什么是文件描述符? 在网络中,一个socket对象就是1个文件描述符,在文件中,1个文件句柄(即file对象)就是1个文件描述符.其实可以理解为就是一个“指针”或“句柄”, ...

  7. Python之网络编程之并发编程的IO模型,

    了解新知识之前需要知道的一些知识 同步(synchronous):一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行 #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调 ...

  8. 从 Linux 操作系统谈谈 IO 模型(终)

    Linux 为什么要区分内核空间与用户空间? Linux 操作系统的 IO 模型有哪几种?有啥区别? 常说的阻塞现象,到底是咋回事? 网络编程研发时,那块到底耗时最多,代码是否还有优化空间? 前几期的 ...

  9. 从春节送祝福谈谈 IO 模型(二)

    上期结合程序员小猿用温奶器给孩子热奶的故事,把面试中常聊的“同步.异步与阻塞.非阻塞有啥区别”简单进行普及. 不过,恰逢春节即将到来,应个景,不妨就通过实现新春送祝福的需求,深入了解一下 Java I ...

随机推荐

  1. 修复Nginx的WebDAV功能

    如果想使用WebDAV来实现文件共享,尤其是想使用操作系统内置功能来挂载文件系统的话,省心的话还是用Apache吧. 下文介绍如何用Nginx来实现这个目标.Windows内置的客户端是Microso ...

  2. 负载均衡框架 ribbon 二

    Ribbon 负载均衡机制 官方文档地址:https://github.com/Netflix/ribbon/wiki/Working-with-load-balancers 1. Ribbon 内置 ...

  3. nsq 初学使用日记

    win下更加直观一些,所以不使用liunx 第一步下载 nsq 下载地址 https://github.com/nsqio/nsq.git 使用git clone或者go get 下载下来 第二部 编 ...

  4. MATLAB神经网络(6) PID神经元网络解耦控制算法——多变量系统控制

    6.1 案例背景 6.1.1 PID神经元网络结构 PID神经元网络从结构上可以分为输入层.隐含层和输出层三层,$n$个控制量的PID神经元网络包含$n$个并列的相同子网络,各个子网络间既相互独立,又 ...

  5. Simulink仿真入门到精通(七) Simulink的回调函数

    7.1 什么是回调函数 Callback functions(回调函数)是因某种操作而除法对其调用的函数,如按下按钮或双击操作等. 常用的Simulink回调函数可应用在以下场合: 打开Simulin ...

  6. mysql 如果没有密码 就不能远程连接

    mysql 如果没有密码 就不能远程连接

  7. 表单配置项写法,表单写成JSON数组套对象,一行是一个数组单位,一列是一个对象单位,然后再写一个公共组件读取这个配置,循环加载slot,外层载入slot的自定义部分,比如input select等,这种写法就是把组件嵌套改为配置方式

    表单配置项写法,表单写成JSON数组套对象,一行是一个数组单位,一列是一个对象单位,然后再写一个公共组件读取这个配置,循环加载slot,外层载入slot的自定义部分,比如input select等,这 ...

  8. Asp.net textbox 控件 的 onTextChange 事件

    <asp:TextBox ID="txt_MailType" runat="server" OnTextChanged="exitMailTyp ...

  9. Python3学习之路~9.3 GIL、线程锁之Lock\Rlock\信号量、Event

    一 Python GIL(Global Interpreter Lock) 全局解释器锁 如果一个主机是单核,此时同时启动10个线程,由于CPU执行了上下文的切换,让我们宏观上看上去它们是并行的,但实 ...

  10. 面试刷题11:java系统中io的分类有哪些?

    随着分布式技术的普及和海量数据的增长,io的能力越来越重要,java提供的io模块提供了足够的扩展性来适应. 我是李福春,我在准备面试,今天的问题是: java中的io有哪几种? java中的io分3 ...