NIO系列2:TCP监听绑定
来源:互联网 发布:me软件发布失败 编辑:程序博客网 时间:2024/05/30 13:42
注:本文适合对象需对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 addressesselector.wakeup();// wait for bind resultwait0();}}
从同步注册变为异步注册后就存在一个问题,实际注册绑定时可能存在端口已绑定的异常,在异步情况下就需要线程间通信来通知异常消息,并向调用方反馈。
如上面代码片段中的wait0()方法就是等待绑定结果,若出现绑定异常则抛出
private void wait0() throws IOException {while (!this.endFlag) {try {lock.wait();} catch (InterruptedException e) {throw new IOException(e);}}// reset end flagthis.endFlag = false;if (this.exception != null) {IOException e = exception;this.exception = null;throw e;}}
以上代码也说明了,NIO异步模型转化为同步API导致的模型阻抗付出了额外的代价和开销 --- 线程间通信。至此,完成了TCP服务监听过程,下文将进一步讲述服务接入和数据传输相关设计细节。
- NIO系列2:TCP监听绑定
- NIO系列3:TCP服务接入
- NIO系列4:TCP服务数据读写
- nio系列2
- Java NIO系列2:NIO概述
- Java NIO系列2:NIO概述
- Nio Tcp
- nio tcp之Socket系列通道 (四)
- NIO系列-03-NIO
- NIO监听网络通信
- NIO文章之一个线程同时监听2个socket
- NIO学习系列笔记(2)
- JAVA NIO系列教程(2) Channel
- Java NIO系列教程(2):Channel
- Java NIO系列教程(2):Channel
- Java NIO系列教程(2):Channel
- NIO系列教程--NIO概述
- NIO实现TCP数据传输
- vs2005 C# 当前不会命中断点。还没有为该文档加载任何符号
- Linphone on BlackBerry呼叫xlite报错问题的解决
- java实现统计输入一行string中统计其中各个字符出现的次数
- UTF8和UCS2
- IOC 实现方式
- NIO系列2:TCP监听绑定
- arcgis server could not obtain a license for networkserver
- Android网络开发中如何使用JSON进行网络通信---Android JSON数据通讯方法解析
- 综合
- 日语学习
- 判断 iframe 是否加载完成的完美方法
- PLSQL导入导出数据库
- Android4.0源码编译问题
- 带你深入了解Web站点数据库的分布存储