阻塞式 IO上述场景中,read 的第一个阶段阻塞的,这就是我们常说的阻塞式 IO,即如果read 第一个阶段等待读就绪是阻塞的,我们就称为阻塞式IO:非阻塞式 IO伪非阻塞(多线程)为了让上面操作中的读操作...epoll 基于高效的红黑树结构,提供了三个核心操作,主要流程如下所示:伪代码:listenfd = socket(); // 打开一个网络通信套接字bind(listenfd); /...等待建立连接 epoll_ctl(connfd, ...); // 将新连接加入到 epoll 对象}// 异步线程检测 通过 epoll_wait 阻塞获取可读的套接字new Tread(){...异步 IO发起读请求后,等待操作系统读取完成后通知,完全将功能交给操作系统实现。总结IO 分为等待读就绪和读取数据两个阶段,阻塞和非阻塞指的是等待读就绪阶段。...在我的博客上,你将找到关于Java核心概念、JVM 底层技术、常用框架如Spring和Mybatis 、MySQL等数据库管理、RabbitMQ、Rocketmq等消息中间件、性能优化等内容的深入文章。
多线程阻塞I/O模型 针对单线程阻塞I/O模型的缺点,我们可以使用多线程对其进行改进,使之能并发地对多个客户端同时进行响应。多线程模型的核心就是利用多线程机制为每个客户端分配一个线程。...内核遍历套接字的事件检测 这种方式将套接字的遍历工作交给了操作系统内核,把对套接字遍历的结果组织成一系列的事件列表并返回应用层处理。...内核遍历套接字时已经不用在应用层对所有套接字进行遍历,将遍历工作下移到内核层,这种方式有助于提高检测效率。...虽然只有一个线程,但是它通过把非阻塞读写操作与上面几种检测机制配合就可以实现对多个连接的及时处理,而不会因为某个连接的阻塞操作导致其他连接无法处理。...如图所示,有4个客户端访问服务器,服务器将套接字1和套接字2交由线程1管理,而线程2则管理套接字3和套接字4,通过事件检测及非阻塞读写就可以让每个线程都能高效处理。
2、通用组件只是在封装套接字,操作系统是通过提供套接字来为进程提供网络通讯能力的。所以,不了解套接字编程,往往对组件的性能就没有原理上的认识。...学习套接字编程,关注点主要在:套接字的编程方法有哪些?阻塞套接字的各方法是如何阻塞住当前代码段的?非阻塞套接字上的方法如何不阻塞当前代码段的?IO多路复用机制是怎样与套接字结合的?...应用程序可以把listen时设置的套接字设为非阻塞模式(默认为阻塞模式),这两种模式会导致accept方法有不同的行为。对阻塞套接字,accept行为如下图: ?...这幅图中可以看到,阻塞套接字上使用accept,第一个阶段是等待ACCEPT队列不为空的阶段,它耗时不定,由客户端是否向自己发起了TCP请求而定,可能会耗时很长。...对非阻塞套接字,accept会有两种返回,如下图: ? 非阻塞套接字上的accept,不存在等待ACCEPT队列不为空的阶段,它要么返回成功并拿到建立好的连接,要么返回失败。
前言 说起当前主流NoSql数据库非 Redis 莫属。...为了解决网络IO中的问题,提出了4中网络IO模型: 阻塞IO模型 非阻塞IO模型 多路复用IO模型 异步IO模型 阻塞和非阻塞的概念描述的是用户线程调用内核IO操作的方式:阻塞时指IO操作需要彻底完成后才返回到用户空间...当对一个非阻塞的socket执行read操作时,读操作流程如下图所示: 从图中可以看出,当用户进程发出 read 操作时,如果内核中的数据还没有准备好,那么它不会阻塞用户进程,而是立刻返回一个错误。...文件事件是对套接字操作的抽象,每当一个套接字准备好执行连接应答、写入、读取、关闭等操作时,就会产生一个文件事件。因为一个服务器通常会连接多个套接字,所以多个文件事件有可能会并发地出现。...小总结 一句话描述 IO 多路复用在 Redis 中的应用:Redis 将所有产生事件的套接字都放到一个队列里面,以有序、同步、每次一个套接字的方式向文件事件分派器传送套接字,文件事件分派器根据套接字对应的事件选择响应的处理器进行处理
WSAAsynSelect()函数将套接口自动设置为非阻塞模式。...如果对 Connect 进行非阻塞调用,则可读意味着已经成功连接,连接不成功则不可读。所以通过这样的设定,我们就能够实现对connect连接时间的修改。...int ioctlsocket(SOCKET s, long cmd, u_long FAR * argp ); s为I/O操作的套接字。 cmd为对套接字的操作命令。...WSAAs ynSelect()函数将套接口自动设置为非阻塞模式。...WSAAsynSelect()函数将套接口自动设置为非阻塞模式。
当I/O 操作完毕时,操作系统将这个线程的阻塞状态解除,恢复其对CPU的控制权,令其继续执行。...其最大的缺点是当希望同时处理大量套接字时,将无从下手,其扩展性很差。...当调用该函数时,套接字会自动地设置为非阻塞方式。 由于使用非阻塞套接字在调用函数时,会经常返回WSAEWOULDBLOCK错误。所以在任何时候,都应仔细检查返回代码并作好对“失败”的准备。...因为该做法对系统造成的开销是很大的,并且应用程序至少要调用recv()函数两次,才能实际地读入数据。较好的做法是,使用套接字的“I/O模型”来判断非阻塞套接字是否可读可写。...使用非阻塞模式套接字,需要编写更多的代码,以便在每个Windows Sockets API函数调用中,对收到的WSAEWOULDBLOCK错误进行处理。因此,非阻塞套接字便显得有些难于使用。
上图中进程在从调用recvfrom开始到它返回的整段时间内被阻塞,recvfrom成功返回后,应用进程开始数据处理 (2)非阻塞式I/O 进程把一个套接字设置成非阻塞是在通知内核:当所请求的I/...当一个应用程序使用了非阻塞模式的套接字,它需要使用一个循环来不停的测试是否一个文件描述符有数据可读(称做 polling,轮询) 。应用程序不停的 polling内核来检查是否 I/O操作已经就绪。...FIN的TCP连接).对这样的套接字读操作,返回0(EOF) c.该套接字是一个监听套接字且已经完成的连接数不为0.对这样的套按字的accept通常不会阻塞 d.其上有一个套接字错误待处理.对这样的套按字的读操作将不阻塞并返回....并且或者该套接已经连接,或者套按字不需要连接(UDP),如果我们把这套接字设置成非阻塞,写操作将不阻塞并返回一个正值.可以使用SO_SNDLOWAT设置一个该套接字的低水位标记.对于TCP和UDP默认值通常为...b.该连接的写半部关闭.对这样的套接写的写操作将产生SIGPIPE信号. c.使用非阻塞式的connect的套按字已经建立连接,或者connect已经失败. d.其上有一个套接字错误等处理。
当I/O 操作完毕时, 操作系统将这个线程的阻塞状态解除,恢复其对CPU的控制权, 令其继续执行。...当调用该函数时,套接字会自动地设置为非阻塞方式。 由于使用非阻塞套接字在调用函数时,会经常返回WSAEWOULDBLOCK错误。所以在任何时候,都应仔细检查返回代码并作好对“失败”的准备。...因为该做法对系统造成的开销是很大的,并且应用程序至少要调用recv()函数两次,才能实际地读入数据。较好的做法是,使用套接字的“I/O模型”来判断非阻塞套接字是否可读可写。...非阻塞模式套接字与阻塞模式套接字相比,不容易使用。...使用非阻塞模式套接字,需要编写更多的代码,以便在每个Windows Sockets API函数调用中,对收到的WSAEWOULDBLOCK错误进行处理。
好勒,就是写IO模型,配上线程/进程所向披靡(网络编程的核心) 非阻塞IO之读(继续查阅资料) 咱们知道套接字有个缓冲区,如果缓冲区没有数据可读,那么在非阻塞的情况下调用read就会立即返回,返回自然会有个状态...在非阻塞的模式下,能写入多少则写入多少,并返回实际写入的字节数 当使用fgets等待标准输入的时候,如果此时套接字有数据但不能读出。...+ 单线程 我们的程序可以通过轮询的方式对套接字进行挨个访问,从而找出进行IO处理的套接字。...在这里插入图片描述 描述符少还行,如果太多,每次的循环将消耗大量的CPU时间,而且可能循环完了都没发现一个套接字可以读写。既然这样,我们直接交给操作系统,让它告诉我们哪些套接字可以读写。...程序就变为这样 poll 我们每次dispatch就相当于对所有的套接字进行排查,这样显然效率不是很高。
与传统的同步 I/O 不同,Java NIO 中的通道操作是非阻塞的,这意味着在发起 IO 请求后,进程可以继续执行其他任务,而不需要等待 IO 操作完成。...相反,你将注册对特定 I/O 事件的兴趣 ― 可读的数据的到达、新的套接字连接,等等,而在发生这样的事件时,系统将会告诉你。...第二行将 ServerSocketChannel 设置为 非阻塞的 。我们必须对每一个要使用的套接字通道调用这个方法,否则异步 I/O 就不能工作。...接受新的连接 因为我们知道这个服务器套接字上有一个传入连接在等待,所以可以安全地接受它;也就是说,不用担心 accept() 操作会阻塞: ServerSocketChannel ssc = (ServerSocketChannel...)key.channel(); SocketChannel sc = ssc.accept(); 下一步是将新连接的 SocketChannel 配置为非阻塞的。
这是由于服务端accept获取到第一个client的套接字后,由于第一个client未输入数据,所以服务端进程会阻塞在等待客户端数据那一行。...新获取到一个套接字后,将该套接字添加到wq中,等到套接字可读写时,操作系统会将该套接字从wq转到rdlist,然后线程直接处理rdlist中的套接字即可,不需要再遍历全部监听的套接字了。...第二处是在获取到accept_fd后,将fd设置为非阻塞了。下面我们展开具体讲讲。 非阻塞与IO多路复用更搭 首先我们先聊聊阻塞IO调用和非阻塞IO调用的区别。...阻塞IO调用:进程在调用IO操作时,如果没有数据可读或缓冲区没有空闲空间可写,导致IO操作未完成,进程被阻塞挂起,后续操作将无法执行。...非阻塞IO调用: 进程在调用IO操作时,即使IO操作未完成,该IO调用也会立刻返回,之后进程可以进行后续操作。
由于我们对结果的关注,所以一定要注意第一个参数的正确性,否则本该置为1的描述字可能会被置为0。 函数的返回值表示所有三个描述字集中已经准备好的总位数,有三种情况: 返回0。...连接的读这一半关闭(接收到FIN分节),套接口的读操作将不阻塞并且返回0(即文件结束符)。 套接口是监听套接口且已完成的连接非0。 有一个套接口错误待处理。...套接口的读操作将不阻塞并且返回一个错误(-1)。...套接口的写操作将不阻塞并且返回大于0的值(例如传输层接收的字节数)。 连接的写这一半关闭,对这样的套接口的写操作将产生信号SIGPIPE。 有一个套接口错误待处理。...套接口的读操作将不阻塞并且返回一个错误(-1)。
进程发起非阻塞IO请求并返回Ewoulfblock后将再次发起非阻塞IO请求。而该行为仍然会使用CPU,称轮询,即polling。...首先来看下可读事件与可写事件: 当如下任一情况发生时,会产生套接字的可读事件: 该套接字的接收缓冲区中的数据字节数大于等于套接字接收缓冲区低水位标记的大小; 该套接字的读半部关闭(也就是收到了FIN),...对这样的套接字的读操作将返回0(也就是返回EOF); 该套接字是一个监听套接字且已完成的连接数不为0; 该套接字有错误待处理,对这样的套接字的读操作将返回-1。...当如下任一情况发生时,会产生套接字的可写事件: 该套接字的发送缓冲区中的可用空间字节数大于等于套接字发送缓冲区低水位标记的大小; 该套接字的写半部关闭,继续写会产生SIGPIPE信号; 非阻塞模式下,connect...返回之后,该套接字连接成功或失败; 该套接字有错误待处理,对这样的套接字的写操作将返回-1。
可选通道的使用大致过程如下: 1.新建通道。 2.将通道的事件注册到选择器Selector上。 3.通过SelectKey获得需要处理的通道,然后对通道进行处理。...2.1.3bind(SocketAddress) 绑定一个本地的套接字地址。 2.1.4setOption(SocketOption, T) 设置套接字的操作方式。...3.1.2bind() 将通道的套接字与本地地址绑定,并且配置套接字监听连接。 此方法有两个重载。...3.1.4socket() 获取服务器关联的套接字。 3.1.5validOps() 返回一个操作集,表示次通道支持的操作。...3.1.6setOption(SocketOption, T) 设置服务器操作集。 3.1.7getLocalAddress() 获取服务器套接字关联的地址。
其最大的缺点是当希望同时处理大量套接字时,将无从下手,其扩展性很差 非阻塞IO模型 简介:非阻塞IO通过进程反复调用IO函数(多次系统调用,并马上返回);在数据拷贝的过程中,进程是阻塞的; ...当调用该函数时,套接字会自动地设置为非阻塞方式。 由于使用非阻塞套接字在调用函数时,会经常返回WSAEWOULDBLOCK错误。所以在任何时候,都应仔细检查返回代码并作好对“失败”的准备。...因为该做法对系统造成的开销是很大的,并且应用程序至少要调用recv()函数两次,才能实际地读入数据。较好的做法是,使用套接字的“I/O模型”来判断非阻塞套接字是否可读可写。 ...非阻塞模式套接字与阻塞模式套接字相比,不容易使用。...使用非阻塞模式套接字,需要编写更多的代码,以便在每个Windows Sockets API函数调用中,对收到的WSAEWOULDBLOCK错误进行处理。
例如,在使用阻塞套接字接收数据时,如果没有数据可用,则调用函数将一直阻塞,直到有数据可用为止。在这种模式下,I/O操作将会一直阻塞应用程序的进程,因此无法执行其他任务。...例如,在使用非阻塞套接字接收数据时,如果没有数据可用,则调用函数将立即返回,并指示操作正在进行中,同时应用程序可以执行其他任务。...非阻塞模式所依赖的核心函数为select()函数是一种用于多路I/O复用的系统调用,在Windows中提供了对该系统调用的支持。...套接字为非阻塞模式。...非阻塞套接字可以使程序不会在等待数据到来时一直阻塞,而是可以在等待数据到来的同时进行其他操作,从而提高程序的效率。
引言 本文介绍网络IO编程的入门部分,Java 的传统BIO Socket编程源码分析,了解如何将BIO阻塞行为accept() 和 read() 改造为非阻塞行为,并且将结合Linux文档介绍其中的机制...在这个选项被设置为非零超时的情况下,对这个ServerSocket的accept()的调用将只阻塞这个时间量。...如果通道处于非阻塞模式,那么输入流的读操作将抛出java.nio.channel.IllegalBlockingModeException。...第一个问题的解决策略是启动多线程以非阻塞read()方式轮询,这样做的另一点好处是,某个Socket读写压力大并不会影响CPU 切到其他线程的正常工作。...它提取出所监听套接字的等待连接队列中第一个连接请求,创建一个新的套接字,并返回指向该套接字的文件描述符。新建立的套接字不在监听状态,原来所监听的套接字也不受该系统调用的影响。
Part1引言 本文介绍网络IO编程的入门部分,Java 的传统BIO Socket编程源码分析,了解如何将BIO阻塞行为accept() 和 read() 改造为非阻塞行为,并且将结合Linux文档介绍其中的机制...在这个选项被设置为非零超时的情况下,对这个ServerSocket的accept()的调用将只阻塞这个时间量。...如果通道处于非阻塞模式,那么输入流的读操作将抛出java.nio.channel.IllegalBlockingModeException。...第一个问题的解决策略是启动多线程以非阻塞read()方式轮询,这样做的另一点好处是,某个Socket读写压力大并不会影响CPU 切到其他线程的正常工作。...它提取出所监听套接字的等待连接队列中第一个连接请求,创建一个新的套接字,并返回指向该套接字的文件描述符。新建立的套接字不在监听状态,原来所监听的套接字也不受该系统调用的影响。
在互联网技术服务行业工作多年的经验告诉我,如果你对底层机制不了解,你就会不明白为什么对套接字socket的读写会出现各种奇奇乖乖的问题,为什么有时会阻塞,有时又不阻塞,有时候还报错,为什么会有粘包半包问题...请读者仔细观察这个动画,后面的讲解将围绕着这个动画展开。 ? img 我们平时用到的套接字其实只是一个引用(一个对象ID),这个套接字对象实际上是放在操作系统内核中。...当我们对客户端的socket写入字节数组时(序列化后的请求消息对象req),是将字节数组拷贝到内核区套接字对象的write buffer中,内核网络模块会有单独的线程负责不停地将write buffer...不过有了NIO(非阻塞IO),写操作也可以不阻塞,能写多少是多少,通过返回值来确定到底写进去多少,那些没有写进去的内容用户程序会缓存起来,后续会继续重试写入。...同样我们也注意到read buffer的内容可能会是空的。这样套接字的读操作(一般是读一个定长的字节数组)也会阻塞,直到read buffer中有了足够的内容(填充满字节数组)才会返回。
,我们需要向 ServerSocketChannel 进行标识,那么它是否提供了对用的方法设置 同步异步(阻塞非阻塞) 呢?...服务端套接字通道 是否阻塞模式。...InetSocketAddress有一个需要一个port为参数的构造方法,它将创建 一个ip为通配符、端口为指定值的套接字地址 。这很方便我们的开发,对吧?...首先要先介绍以下JDK实现NIO的核心:多路复用器(Selector)——选择器 先简单并抽象的理解下,Java通过 选择器来实现处理多个Channel链接 ,将空闲未进行数据操作的搁置,优先执行有需求的数据传输.... */ public abstract int select() throws IOException; } 好的,看样子是对的,它将返回一组套接字通道已经准备好执行I/O操作的键
领取专属 10元无门槛券
手把手带您无忧上云