注:本文适合对象需对java NIO API的使用及异步事件模型(Reactor模式)有一定程度的了解,主要讲述使用java原生NIO实现一个TCP监听绑定的过程及细节设计。
我们一开始设计了一个TCP接入服务类,这个类提供了一个API方法提供对本地一系列地址(端口)的监听绑定,类初始化后完成Selector的open操作如下:
selector = Selector.open();
提供的绑定API,其方法签名如下:
/**
* Binds to the specified local addresses and start to accept incoming connections. If any address binding failed then
* rollback the already binding addresses. Bind is fail fast, if encounter the first bind exception then throw it immediately.
*
* @param firstLocalAddress
* @param otherLocalAddresses
* @throws throw if bind failed.
*/
synchronized public void bind(SocketAddress firstLocalAddress, SocketAddress... otherLocalAddresses) throws IOException;
为何需要同步?因为我们不希望多个线程同时调用该方法,导致地址绑定异常。
参数中可以传递多个本地地址(端口)同时进行监听绑定。
在NIO的绑定过程中需进行事件注册(对OP_ACCEPT感兴趣),如下:
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
ServerSocket ss = ssc.socket();
ss.setReuseAddress(config.isReuseAddress());
ss.bind(address, config.getBacklog());
ssc.register(selector, SelectionKey.OP_ACCEPT);
由于注册过程中除了涉及锁竞争还可能产生死锁,所以一般的做法都是将绑定地址放在队列中进行异步注册由reactor线程进行处理,例如:
bindAddresses.addAll(localAddresses);
if (!bindAddresses.isEmpty()) {
synchronized (lock) {
// wake up for unblocking the select() to process binding addresses
selector.wakeup();
// wait for bind result
wait0();
}
}
从同步注册变为异步注册后就存在一个问题,实际注册绑定时可能存在端口已绑定的异常,在异步情况下就需要线程间通信来通知异常消息,并向调用方反馈。
如上面代码片段中的wait0()方法就是等待绑定结果,若出现绑定异常则抛出
private void wait0() throws IOException {
while (!this.endFlag) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new IOException(e);
}
}
// reset end flag
this.endFlag = false;
if (this.exception != null) {
IOException e = exception;
this.exception = null;
throw e;
}
}
以上代码也说明了,NIO异步模型转化为同步API导致的模型阻抗付出了额外的代价和开销 --- 线程间通信。
至此,完成了TCP服务监听过程,下文将进一步讲述服务接入和数据传输相关设计细节。
分享到:
相关推荐
NULL 博文链接:https://zhangshixi.iteye.com/blog/683767
NULL 博文链接:https://zhangshixi.iteye.com/blog/679959
TCP NIO socket TCP服务器,支持多个客户端连接
NULL 博文链接:https://zhangshixi.iteye.com/blog/685022
利用磁控溅射法,在ITO玻璃基底上沉积NiO薄膜和ZnO:Al(Al掺杂的ZnO或AZO)薄膜,制备具有半导体特性的NiO/ZnO:A1透明异质结二极管。使用UV-1700型分光光度计、KEITHLEY4200-SCS半导体测试仪、JSM-6490LV型扫描电子...
NULL 博文链接:https://zhangshixi.iteye.com/blog/684544
NIO.2插座测试仪 一个演示应用程序,用于检查是否可以使用在TCP套接字的另一端读取所有成功的写入。 建造 仅通过从命令行运行ant即可在NetBeans中构建... java -cp Nio2Test.jar nio2test.Nio2TestClient [servername]
赠送jar包:httpcore-nio-4.4.6.jar; 赠送原API文档:httpcore-nio-4.4.6-javadoc.jar; 赠送源代码:httpcore-nio-4.4.6-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.6.pom; 包含翻译后的API文档:...
NIO java nio 简介 Java NIO(New IO)是用于Java(来自Java 1.4)的替代IO API,意味着替代标准 Java IO和Java Networking API。 Java NIO提供了与原来IO API不同的工作方式,但是作用和目的是一样的。 NIO支持面向...
clj-async-tcp-echo-nio.2 Clojure 中的异步 TCP 回显客户端/服务器,使用 Java 7 NIO.2。 Java 文档是详尽的,即使不一定是示例的最佳来源。 您可以使用 、 、 和获得所需的背景。用法在一个 REPL 中,启动一个...
赠送jar包:xnio-nio-3.8.4.Final.jar; 赠送原API文档:xnio-nio-3.8.4.Final-javadoc.jar; 赠送源代码:xnio-nio-3.8.4.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.4.Final.pom; 包含翻译后的API...
相同的回显服务器,但使用NIO2异步通道。 创建10000个客户端连接的类,您可以在nio服务器上测试负载。 监视服务API的简单用法。 监视预定义目录中的更改的类。 您可以播放生成的jar文件。 请按照以下步骤操作: ...
Java NIO系列教程(一) Java NIO 概述 Java NIO系列教程(二) Channel Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六)...
nio-study:尼奥研究
java7 源码 java-nio-master java Nio 主要内容: (1) 按操作方式分类结构图: (2)按操作对象分类结构图 IO流的分类: 按照流的流向分,可以分为输入流和...2)IO流是阻塞的,NIO流是不阻塞的; 3)NIO有选择器,而
Java NIO系列教程(一) Java NIO 概述
赠送jar包:httpcore-nio-4.4.15.jar 赠送原API文档:httpcore-nio-4.4.15-javadoc.jar 赠送源代码:httpcore-nio-4.4.15-sources.jar 包含翻译后的API文档:httpcore-nio-4.4.15-javadoc-API文档-中文(简体)版....
赠送jar包:httpcore-nio-4.4.6.jar 赠送原API文档:httpcore-nio-4.4.6-javadoc.jar 赠送源代码:httpcore-nio-4.4.6-sources.jar 包含翻译后的API文档:httpcore-nio-4.4.6-javadoc-API文档-中文(简体)版.zip ...
nio-demo NIO编程demo 主要内容: 1、使用NIO实现文件读写,文件拷贝 2、使用NIO实现Socket编程 注:com.minghui.nio.demo包下是IBM官方demo
nio_proxy 基本的 nio 代理