【Java网络编程】:JDK API实现OIO和NIO
前言
网络编程是Java的一大难点,JDK自带的api可以实现网络编程。
我们将从一个应用程序开始我们对传输的学习,这个应用程序只简单地接受连接,然后向客户端写“Hi!”,然后关闭连接。
1. OIO实现
应用程序的阻塞(OIO)版代码如下:
package chx.demo;import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;public class PlainOioServer {public void serve(int port) throws IOException {//1. 将服务器绑定到指定端口final ServerSocket socket = new ServerSocket(port);try {for(;;) {// 2. for循环不断地接受连接final Socket clientSocket = socket.accept();System.out.println("Accepted connection from " + clientSocket);// 3. 创建一个新的线程来处理该连接new Thread(new Runnable() {@Overridepublic void run() {OutputStream out;try {// 4. 将消息写给已连接的客户端out = clientSocket.getOutputStream();out.write("Hi!\r\n".getBytes(Charset.forName("UTF-8")));out.flush();// 5. 关闭连接clientSocket.close();} catch (IOException e) {e.printStackTrace();} finally {try {clientSocket.close();} catch (IOException ex) {// ignore on close}}// 7.启动线程}}).start();}} catch (IOException e) {e.printStackTrace();}}
}
这段代码完全可以处理中等数量的并发客户端。但是随着应用程序变得流行起来,你会发现它并不能很好地伸缩到支撑成千上万的并发连入连接。
你决定改用异步网络编程,但是很快就发现异步API 是完全不同的,以至于现在你不得不重写你的应用程序。
2. NIO实现
其非阻塞版代码如下:
package nia.chapter4;import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;public class PlainNioServer {public void serve(int port) throws IOException {// 实例化ServerSocketChannelServerSocketChannel serverChannel = ServerSocketChannel.open();serverChannel.configureBlocking(false);ServerSocket ss = serverChannel.socket();InetSocketAddress address = new InetSocketAddress(port);// 1. 将服务器绑定到选定的端口ss.bind(address);// 2. 打开Selector来处理 ChannelSelector selector = Selector.open();// 3. 将ServerSocketChannel注册到Selector以接受连接serverChannel.register(selector, SelectionKey.OP_ACCEPT);final ByteBuffer msg = ByteBuffer.wrap("Hi!\r\n".getBytes());for (;;){try {// 4. 等待需要处理的新事件;阻塞将一直持续到下一个传入事件selector.select();} catch (IOException ex) {ex.printStackTrace();//handle exceptionbreak;}// 5. 获取所有接收事件的SelectionKey实例Set<SelectionKey> readyKeys = selector.selectedKeys();Iterator<SelectionKey> iterator = readyKeys.iterator();while (iterator.hasNext()) {SelectionKey key = iterator.next();iterator.remove();try {// 6.检查事件是否是一个新的已经就绪可以被接受的连接if (key.isAcceptable()) {ServerSocketChannel server =(ServerSocketChannel) key.channel();SocketChannel client = server.accept();client.configureBlocking(false);// 7.接受客户端,并将它注册到选择器client.register(selector, SelectionKey.OP_WRITE |SelectionKey.OP_READ, msg.duplicate());System.out.println("Accepted connection from " + client);}// 8.检查套接字是否已经准备好写数据if (key.isWritable()) {SocketChannel client =(SocketChannel) key.channel();ByteBuffer buffer =(ByteBuffer) key.attachment();while (buffer.hasRemaining()) {// 9. 将数据写到已连接的客户端if (client.write(buffer) == 0) {break;}}// 10.关闭连接client.close();}} catch (IOException ex) {key.cancel();try {key.channel().close();} catch (IOException cex) {// ignore on close}}}}}
}
如同你所看到的,虽然这段代码所做的事情与之前的版本完全相同,但是代码却截然不同。
如果为了用于非阻塞I/O 而重新实现这个简单的应用程序,都需要一次完全的重写的话,那么不难想象,移植真正复杂的应用程序需要付出什么样的努力。
所以Java JDK原生实现NIO是比较复杂的,学习门槛比较大。这个时候就轮到Netty闪亮登场了。
【Java网络编程】:JDK API实现OIO和NIO相关推荐
- Java网络编程进化史:从IO到NIO再到Netty
一.Netty入门 1.传统IO与NIO NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多. ...
- Java 网络编程API以及实例
Java 网络编程 网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来. java.net包中J2SE的API包含有类和接口,它们提供低层次的通信细节.你可以直接使用这些类和接 ...
- NIO详解(一):java网络编程IO总结(BIO、NIO、AIO)
1.基本概念 在Java网络通信中,最基本的概念就是Socket编程了.Socket又称"套接字" 向网络发出请求或者应答网络请求. Socket 和ServerSocket类库位 ...
- JAVA网络编程知识学习
JAVA网络编程知识学习 学习目标 第一章 网络编程入门 1.1软件结构 1.2 网络通信协议 1.3 协议分类 1.4 网络编程三要素 协议 IP地址 IP地址分类 常用命令 端口号 InetAdd ...
- Java 网络编程系列之 NIO
Java 网络编程系列之 NIO 第 1 章Java NIO 概述 1.1 IO 概述 IO 的操作方式 1.2 阻塞 IO (BIO) 1.3 非阻塞 IO(NIO) 1.4 异步非阻塞 IO(AI ...
- 04.Java网络编程(转载)
1.网络编程 1.1计算机网络概述 网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输. 按照计算机网络的定义,通过一定的物理设备将处于不同位置的计算机连接起来组成的网络,这个网络中包含 ...
- python网络编程视频教程_Java网络开发视频教程 – 一站式学习Java网络编程视频教程 全面理解BIO(无密)...
Java网络开发视频教程 – 一站式学习Java网络编程视频教程 全面理解BIO(无密) 全面理解BIO/NIO/AIO 网络层编程,是每一个开发者都要面对的技术.课程为解决大家学习网络层知识的难题, ...
- java网络编程(二)
注意:架构师学习资源已更新. 获取方式:在公众号内回复"架构师资源" 文章推荐 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 1.2 网络编程技术 前面介绍 ...
- 【带你入门】java网络编程
网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编 ...
最新文章
- 用vs2010编译vigra静态库及简单使用举例
- SVN用户验证,调错
- Taro+react开发(95):问答模块02
- 计算火车运行时间(pta)
- 592zn rom/apk 自动签名工具_关于邮件签名证书的常见问题
- iview 下拉select样式_Ant Design 4.0 的一些杂事儿 - Select 篇
- CetnOS 6.7安装Hive 1.2.1
- PIL图像处理模块paste方法简单使用
- 论文阅读笔记——拥塞控制算法PCC
- 注解缓存@Cacheable、CachePut、CacheEvict、Caching使用及介绍
- python爬网易评论
- React实现获取验证码倒计时
- java web景点规划导航
- [TcaplusDB|黎明觉醒] 一路相伴,不负期待
- 如何修改图片的dpi?图片怎么调dpi?
- 数据分析师的就业前景如何?
- VPP学习(二)VPP安装
- C/C++文件输入输出(详细介绍)
- 《真实的幸福》读书总结
- 月薪 6149.55!博士毕业,大学任教...
热门文章
- C语言中task的用法,c – 在std :: packaged_task中使用成员函数
- css解决文字抖动问题
- win10无线网卡无法连接网络
- visual stadio code(VS code) 中 Markdown简明操作[持续更新]
- javascript网页设计期末作业 购物网站
- excel如何晒出重复数据_excel 如何在大量数据中快速筛选出重复数据
- 弘辽科技:如何写出自带流量的标题
- 微信小游戏开发实战教程13-随机生成形状功能的实现
- Android开发 之 OpenGL ES系列(5--3D立体图形)
- 谷歌浏览器突然不能翻译了怎么解决?无法翻译此网页的解决方法