5

NIO:1、Soecket Socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。一个Socket由一个IP地址和一个端口号唯一确定。Socket的基本工作过程包含以下四个步骤:1、创建Socket;2、打开连接到Socket的输入输出流;3、按照一定的协议对Socket进行读写操作;4、关闭Socket。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。

Server:ServerSocket serverSocket =new ServerSocket(2013);Socket socket = serverSocket.accept(); //接受到此Socket的连接,在socket连接之前,将阻塞// 由Socket对象得到输入流,并构造相应的BufferedReader对象BufferedReader bufferedReader =new BufferedReader(new InputStreamReader(socket.getInputStream()));// 获取从客户端读入的字符串String result = bufferedReader.readLine(); //在获取客户端输入之前,又将阻塞//服务端发送给客户端PrintWriter printWriter =new PrintWriter(socket.getOutputStream());printWriter.print("hello Client, I am Server!");printWriter.flush();// 关闭SocketprintWriter.close();bufferedReader.close();socket.close();

Client:// 创建SocketSocket socket =new Socket("127.0.0.1",2013);socket.setSoTimeout(60000); // 60s超时//发给服务端PrintWriter printWriter =new PrintWriter(socket.getOutputStream(),true);printWriter.println("Hi, im cliet.");printWriter.flush();//接收服务端消息,由Socket对象得到输入流BufferedReader bufferedReader =new BufferedReader(new InputStreamReader(socket.getInputStream()));String result = bufferedReader.readLine(); //若一直未接收到,则阻塞System.out.println("Server say : " + result);

2、IO阻塞

当一个IO读操作发生时,通常经历两个步骤:1,等待数据准备2,将数据从系统内核拷贝到操作进程中JDK1.4提供了对非阻塞IO(NIO)的支持,JDK1.5_update10版本使用epoll替代了传统的select/poll,极大的提升了NIO通信的性能I/O 模型可以分为:同步阻塞,同步非阻塞,异步阻塞,异步非阻塞同步阻塞:在此种方式下,用户进程在发起一个 IO 操作以后,必须等待 IO 操作的完成,只有当真正完成了 IO 操作以后,用户进程才能运行。 JAVA传统的 IO 模型属于此种方式!同步非阻塞:用户进程发起一个 IO 操作以后 边可 返回做其它事情,但是用户进程需要时不时的询问 IO 操作是否就绪,这就要求用户进程不停的去询问,从而引入不必要的 CPU 资源浪费。非阻塞:体现在,这个线程可以去干别的,不需要一直在这等着同步:体现在消息通知机制,这个线程仍然要定时的读取stream,判断数据有没有准备好,client采用循环的方式去读取,可以看出CPU大部分被浪费了其中目前 JAVA 的 NIO 就属于同步非阻塞 IO 。异步非阻塞:服务端调用read()方法,若stream中无数据则返回,程序继续向下执行。 当stream中有数据时,操作系统会负责把数据拷贝到用户空间,然后通知这个线程,这里的消息通知机制就是异步! 而不是像NIO那样,自己起一个线程去监控stream里面有没有数据!

IO多路复用 & Reactor模式(反应器模式,事件驱动):https://zhuanlan.zhihu.com/p/27382996https://zhuanlan.zhihu.com/p/27419141

3、NIO三大组件

Chanel/Buffer/Selector

通道和缓冲区,NIO最主要的两个组件。NIO 是基于块 (Block) 的,它以块为基本单位处理数据Buffer 是一块连续的内存块,是 NIO 读写数据的中转地。通道标识缓冲数据的源头或者目的地,它用于向缓冲读取或者写入数据Chanel 是一个双向通道,可读亦可写,对应于传统IO的流Stream,Stream是单向的关系:数据可以从通道读入缓冲区,也可以从缓冲区写入到通道中。int bytesRead = inChannel.read(buf); //read into buffer.int bytesWritten = inChannel.write(buf);//read from buffer into channel.这里的read/write都是channel提供的,故都是以channel角度来看的:read,从channel读数据 => 写入到buf;write,写数据到channel=> 从buf 读数据Buffer:capacity:作为一个内存块,Buffer有一个固定的大小值。一旦Buffer满了,需要将其清空(通过读数据或者清除数据)才能继续写数据往里写数据limit:在读模式下,Buffer的limit表示你最多能往Buffer里写多少数据。写模式下,limit等于Buffer的capacityposition:写数据到Buffer中时,position表示当前的位置。初始的position值为0.position最大可为capacity – 1. 读取数据时,也是从某个特定位置读,当从Buffer的position处读取数据时,position向前移动到下一个可读的位置。 当将Buffer从写模式切换到读模式,position会被重置为0. 

Selector:http://www.molotang.com/articles/906.htmlhttps://segmentfault.com/a/1190000006824196http://ifeve.com/selectors/

1、通过 Selector.open() 打开一个 Selector.2、将 Channel 注册到 Selector 中, 并设置需要监听的事件(interest set)3、不断重复: 调用 select() 方法, 调用 selector.selectedKeys() 获取 selected keys,迭代每个 selected key: 从 selected key 中获取 对应的 Channel ,判断是哪些 IO 事件已经就绪了, 然后处理它们; 将已经处理过的 key 从 selected keys 集合中删除.// 打开服务端 SocketServerSocketChannel serverSocketChannel = ServerSocketChannel.open();// 打开 SelectorSelector selector = Selector.open();// 服务端 Socket 监听8080端口, 并配置为非阻塞模式serverSocketChannel.socket().bind(new InetSocketAddress(8080));serverSocketChannel.configureBlocking(false);// 将 channel 注册到 selector 中.// 通常先注册一个 OP_ACCEPT 事件, 然后在 OP_ACCEPT 到来时, 再将这个 Channel 的 OP_READ,注册到 Selector 中。serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);//不断轮询while (true) { // 通过调用 select 方法, 阻塞地等待 channel I/O 可操作 if (selector.select(TIMEOUT) == 0) { System.out.print("."); continue; } // 获取 I/O 操作就绪的 SelectionKey, 通过 SelectionKey 可以知道哪些 Channel 的哪类 I/O 操作已经就绪. Iterator keyIterator = selector.selectedKeys().iterator();

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容