踏莎行·术 - NIO系列2:TCP监听绑定
注:本文适合对象需对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系列4:TCP服务数据读写
注:本文适合对象需对java NIO API的使用及异步事件模型(Reactor模式)有一定程度的了解,主要讲述使用java原生NIO实现一个TCP服务的过程及细节设计. 上文讲到当客户端完成与服务端 ...
- 踏莎行·术 - NIO系列3:TCP服务接入
注:本文适合对象需对java NIO API的使用及异步事件模型(Reactor模式)有一定程度的了解,主要讲述使用java原生NIO实现一个TCP服务的过程及细节设计. 前文讲述了NIO TCP服务 ...
- 踏莎行·术 - NIO系列1:框架拆解
最近一年用NIO写了不少网络程序,也研究了一些开源NIO网络框架netty.mina等,总结了一下NIO的架构特点. 无论是netty还是mina它们都在java原生NIO的基础上进行了完善的封装,虽 ...
- 踏莎行·术 - NIO系列5:事件模型
前文讲述了NIO数据读写处理,那么这些数据最终如何被递交给上层业务程序进行处理的呢? NIO框架一般都采用了事件派发模型来与业务处理器交互,它与原生NIO的事件机制是模型匹配的,缺点是带来了业务处理的 ...
- zabbix自动发现规则实现批量监控主机的TCP监听端口
检查服务器所有监听端口和其对应的服务名称的脚本可以参考https://blog.zzyyxx.top/blog/post/gordy/acf57f04f9e1 现在准备加入zabbix自动发现规则并 ...
- python 监听tcp端口_创建TCP监听_创建TCP监听_功能示例_Python SDK示例_SDK 参考_开发指南_负载均衡 - 阿里云...
# encoding=utf-8 import json import sys # 调用AcsClient参数进行身份验证 from aliyunsdkcore.client import AcsCl ...
- linux 内核参数somaxconn TCP监听队列长度
在Linux中,/proc/sys/net/core/somaxconn这个参数,linux中内核的一个不错的参数somaxconn. 对于一个TCP连接,Server与Client需要通过三次握手来 ...
- java tcp 监听端口_【TCP/IP】端口未监听,还能访问成功?
作者:Mr林_月生链接:https://www.jianshu.com/p/3ab10c8685b5 现象 直接上图 可以发现,本地没监听50000端口的服务,但是尝试连接本地50000端口时,却能成 ...
- centos7开启tcp6_centos中docker映射出来的端口被tcp6监听,而没有被tcp监听导致ip+端口无法进行访问...
如图,我通过docker构建容器时,映射出来的端口是8081,但是通过ip+8081无法访问,在检查了一遍安全组规则是否开放,以及百度以后查到是由于端口被tcp6监听,没有被tcp监听到导致的. 按照 ...
最新文章
- 在分页状态下删除纪录的问题
- gis快速接地开关_一种基于扫描电镜和能谱仪的GIS放电异物来源分析方法
- 2018 年,去百度面试 Java 后端的一次面试经历
- 使用多级分组报表展现分类数据
- c++对象的动态建立和释放
- linux Figlet 转换字符字
- oracle 中的几天后,几年后
- 图说苹果工作站-MAC PRO
- SAP ABAP和C4C,Hybris Commerce里一些性能分析工具
- 在Ubuntu|CentOS上安装Shutter截图工具及快捷键设置
- 前端学习(2267)vue造轮子之添加icon
- fetch oracle 12c下载,十二、Oracle Fetch子句
- 在线批量身份证识别系统
- header标签为什么不能改变背景颜色呢?
- UWP 手绘视频创作工具技术分享系列 - 文字的解析和绘制
- 人工智能AI实训平台
- 明天终于要到公司开工了
- Docker - volume、-v 区别
- iloc和loc区别和应用总结
- PCB原理图绘制(7)——PCB的设置与布线
热门文章
- 集成zxing扫码解决二维码自动放大
- Final cut pro剪辑视频快捷键汇总
- Ubuntu18.04将Python升级到3.8
- vba excel 开发游戏_VBA代码助手专业版正式发布,让天下没有难写的VBA代码
- 本地计算机上的MySQL服务启动后停止。某些服务在未由其他服务或程序使用时将自动停止
- matlab短均线滞后项,均线延迟的成因及解决
- 一个资深程序员看12306 (二)
- 手机贴膜利润超百倍 消费者为无用功能高价买单
- 《鬼灭之刃 无限列车编》超越《哈尔移动城堡》《哈利波特》成史上第五位
- 小米手环7、小米手环7pro和小米手环7/nfc的区别