Java 网络编程 “初探”

一、概念解析

1、同步与异步

同步与异步同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)

所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是由调用者主动等待这个调用的结果。

而异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。

2、阻塞IO,非阻塞IO

实际上阻塞与非阻塞的概念,通常是针对底层的IO操作来说的。

阻塞IO会一直block住对应的进程直到操作完成,而非阻塞IO在kernel还准备数据的情况下会立刻返回。

阻塞I/O特点是调用I/O操作之后一定要等到系统内核层面完成所有操作之后,调用才返回

非阻塞I/O调用后会立即返回一个文件描述符,调用方的数据再通过文件描述符获取

二、网络编程模型

对于一次IO访问,数据会先被拷贝到内核的缓冲区中,然后才会从内核的缓冲区拷贝到应用程序的地址空间。需要经历两个阶段:

1)准备数据

2)将数据从内核缓冲区拷贝到进程地址空间

由于存在这两个阶段,Linux产生了下面五种IO模型。

1.1、阻塞式I/O模型

1.2、非阻塞式I/O模型

1.3、I/O多路复用(事件驱动)模型

1.4、信号驱动式I/O(SIGIO)

1.5、异步I/O模型

关于这张图的解释:

在说明同步IO和异步IO的区别之前,需要先给出两者的定义。Stevens给出的定义(其实是POSIX的定义)是这样子的:

A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes; An asynchronous I/O operation does not cause the requesting process to be blocked;

两者的区别就在于同步IO做”IO operation”的时候会将process阻塞。按照这个定义,之前所述的阻塞IO,非阻塞IO ,IO复用都属于同步IO。 有人可能会说,非阻塞IO 并没有被block啊。这里有个非常“狡猾”的地方,定义中所指的”IO operation”是指真实的IO操作,就是例子中的recvfrom这个system call。非阻塞IO在执行recvfrom这个system call的时候,如果kernel的数据没有准备好,这时候不会block进程。但是,当kernel中数据准备好的时候,recvfrom会将数据从kernel拷贝到用户内存中,这个时候进程是被block了,在这段时间内,进程是被block的。 而异步IO则不一样,当进程发起IO 操作之后,就直接返回再也不理睬了,直到kernel发送一个信号,告诉进程说IO完成。在这整个过程中,进程完全没有被block。

四、Java的网络io模型

1、最原始的bio模型

2、伪异步io,改进版bio (线程池代替)

3、nio模型

JDK的Selector基于select/poll模型实现 Reactor线程模型

netty的线程模型

4、AIO

JDK1.7引入NIO2.0,提供了异步文件通道和异步套接字通道的实现。其底层在windows上是通过IOCP,在Linux上是通过epoll来实现的

五、简单的java网络代码实现

代码实现:https://github.com/qiaozhiyong/javaNio

六、参考文章

先读篇:

聊聊Unix与Java的IO模型 (返璞归真篇) https://mp.weixin.qq.com/s/mEahtWqeFqzzaETHKAWtzw

linux io 模型 https://www.cnblogs.com/lirenzuo/p/8116265.html linux io 模型 通俗理解 https://toutiao.io/posts/ws47d3?from=singlemessage linux io 模型 最通俗 易懂 https://www.jianshu.com/p/511b9cffbdac?hmsr=toutiao.io&utm medium=toutiao.io&utm source=toutiao.io

JAVA的网络IO模型

https://mp.weixin.qq.com/s/zRBH6SJjRqBiZSmK6fREUw (未读懂)

最全的介绍 (包括java 和 linux io) https://www.cnblogs.com/diegodu/p/6823855.html(未读懂)

详解tomcat的连接数与线程池 https://www.cnblogs.com/kismetv/p/7806063.html

网络编程基础知识(必读) https://mp.weixin.qq.com/s? _biz=MzU4ODgyMDI0Mg==&mid=2247485996&idx=1&sn=4cab82d8c3640df1d94cd98ee01e4816&source=41#wechat redirect

半同步 半异步的提出 // 半同步半反应堆 // poll select epoll 解释 https://zhuanlan.zhihu.com/p/58860015?hmsr=toutiao.io&utm medium=toutiao.io&utm source=toutiao.io(不同的解释)

多路复用、非阻塞、线程与协程 (最通俗,引入为什么需要多路复用+go现实实现逻辑)

https://www.nosuchfield.com/2019/01/09/Multiplex-and-non-blocking-and-threading-and-coroutine/

为什么 多路复用 是 异步阻塞的解释 https://www.jianshu.com/p/2f2fe920ed25

reactor的发展史 https://www.cnblogs.com/doit8791/p/7461479.html

选读篇:

Linux网络编程之IO模型 https://mp.weixin.qq.com/s/b-5AZnWNMfzZ2xZb 6 mgw

零拷贝及 java上的应用

https://mp.weixin.qq.com/s/cR5gEpapE-V43Pi4LoET8g

java nio 基础篇

https://mp.weixin.qq.com/s? _biz=MzU2NjIzNDk5NQ==&mid=2247483837&idx=1&sn=b51954fd4644feeddde61daed5d273b6&scene=21#wechat redirect

java nio 实战篇

https://blog.csdn.net/elricboa/article/details/79034617

Java网络编程- IO多路复用(多Reactor)(主从式Reactor) 三篇

https://blog.csdn.net/weililansehudiefei/article/details/70889544

接下来的文章会去重点 研究nio的相关实现,尽情期待

如果喜欢,欢迎关注我的公众号:乔志勇笔记