踏莎行·术 - 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监听到导致的. 按照 ...
最新文章
- Linux完全兼容POSIX1.0标准的特性
- KVM虚拟机源代码分析
- 虚拟键码对照表与ASCII对照表的区别
- Latex入门:编辑器(texmaker+texlive)安装
- 【elasticsearch】文档 CRUD 增删改查 以及 相关 参数
- tensorrt之tensorrtx编译:遇到的错误提示
- php旧物交易开源代码_代码收藏系列--php--生成简短唯一订单号
- 数据结构简单模拟银行排队系统
- 骗术在升级,一定要注意
- c语言高级成分,高级语言的基本成分数据成分,运算成分,控制成分,传输成分,怎么看它们的类型区别的?比如其中对处理对象的类型说明属于高级语...
- B站李旎:学习类内容正从B站开始兴起
- Dubbo源码分析之构建远程Invoker
- 压缩pdf大小的方法分享
- eclipse-查看继承层次图/继承实现层次图
- C程序设计谭浩强版总结笔记
- python Dataframe 根据某一列的值来删除多行
- C++ Test 关于Read Symbols报错的解决方法(适用于Windows 10)
- 在线招聘软件市场深度分析及发展研究预测报告
- 五大智能手机系统对比
- 云客Drupal源码分析之语言Language
热门文章
- 《软件测试》第十一章 易用性测试
- Dashcam Viewer Plus v3.8.0 行车记录仪播放工具
- 达人评测锐龙r7 6850u和 R7 6850HS选哪个好
- 输出重定向Linux命令,Linux Shell重定向(输入输出重定向)精讲
- 在CMD中运行java程序
- 三星手机换新卡显示无服务器,玩机“老炮”告诉你三星手机新玩法
- day01-网络爬虫
- origin账号能买吗_一名Origin用户价值上万的游戏账号被莫名删除 EA客服起初竟拒绝帮他找回丢失的账号...
- 一周日期选择(周一至周日)
- Java8 日期、时间骚操作