注:本文适合对象需对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监听绑定相关推荐

  1. 踏莎行·术 - NIO系列4:TCP服务数据读写

    注:本文适合对象需对java NIO API的使用及异步事件模型(Reactor模式)有一定程度的了解,主要讲述使用java原生NIO实现一个TCP服务的过程及细节设计. 上文讲到当客户端完成与服务端 ...

  2. 踏莎行·术 - NIO系列3:TCP服务接入

    注:本文适合对象需对java NIO API的使用及异步事件模型(Reactor模式)有一定程度的了解,主要讲述使用java原生NIO实现一个TCP服务的过程及细节设计. 前文讲述了NIO TCP服务 ...

  3. 踏莎行·术 - NIO系列1:框架拆解

    最近一年用NIO写了不少网络程序,也研究了一些开源NIO网络框架netty.mina等,总结了一下NIO的架构特点. 无论是netty还是mina它们都在java原生NIO的基础上进行了完善的封装,虽 ...

  4. 踏莎行·术 - NIO系列5:事件模型

    前文讲述了NIO数据读写处理,那么这些数据最终如何被递交给上层业务程序进行处理的呢? NIO框架一般都采用了事件派发模型来与业务处理器交互,它与原生NIO的事件机制是模型匹配的,缺点是带来了业务处理的 ...

  5. zabbix自动发现规则实现批量监控主机的TCP监听端口

    检查服务器所有监听端口和其对应的服务名称的脚本可以参考https://blog.zzyyxx.top/blog/post/gordy/acf57f04f9e1  现在准备加入zabbix自动发现规则并 ...

  6. python 监听tcp端口_创建TCP监听_创建TCP监听_功能示例_Python SDK示例_SDK 参考_开发指南_负载均衡 - 阿里云...

    # encoding=utf-8 import json import sys # 调用AcsClient参数进行身份验证 from aliyunsdkcore.client import AcsCl ...

  7. linux 内核参数somaxconn TCP监听队列长度

    在Linux中,/proc/sys/net/core/somaxconn这个参数,linux中内核的一个不错的参数somaxconn. 对于一个TCP连接,Server与Client需要通过三次握手来 ...

  8. java tcp 监听端口_【TCP/IP】端口未监听,还能访问成功?

    作者:Mr林_月生链接:https://www.jianshu.com/p/3ab10c8685b5 现象 直接上图 可以发现,本地没监听50000端口的服务,但是尝试连接本地50000端口时,却能成 ...

  9. centos7开启tcp6_centos中docker映射出来的端口被tcp6监听,而没有被tcp监听导致ip+端口无法进行访问...

    如图,我通过docker构建容器时,映射出来的端口是8081,但是通过ip+8081无法访问,在检查了一遍安全组规则是否开放,以及百度以后查到是由于端口被tcp6监听,没有被tcp监听到导致的. 按照 ...

最新文章

  1. Linux完全兼容POSIX1.0标准的特性
  2. KVM虚拟机源代码分析
  3. 虚拟键码对照表与ASCII对照表的区别
  4. Latex入门:编辑器(texmaker+texlive)安装
  5. 【elasticsearch】文档 CRUD 增删改查 以及 相关 参数
  6. tensorrt之tensorrtx编译:遇到的错误提示
  7. php旧物交易开源代码_代码收藏系列--php--生成简短唯一订单号
  8. 数据结构简单模拟银行排队系统
  9. 骗术在升级,一定要注意
  10. c语言高级成分,高级语言的基本成分数据成分,运算成分,控制成分,传输成分,怎么看它们的类型区别的?比如其中对处理对象的类型说明属于高级语...
  11. B站李旎:学习类内容正从B站开始兴起
  12. Dubbo源码分析之构建远程Invoker
  13. 压缩pdf大小的方法分享
  14. eclipse-查看继承层次图/继承实现层次图
  15. C程序设计谭浩强版总结笔记
  16. python Dataframe 根据某一列的值来删除多行
  17. C++ Test 关于Read Symbols报错的解决方法(适用于Windows 10)
  18. 在线招聘软件市场深度分析及发展研究预测报告
  19. 五大智能手机系统对比
  20. 云客Drupal源码分析之语言Language

热门文章

  1. 《软件测试》第十一章 易用性测试
  2. Dashcam Viewer Plus v3.8.0 行车记录仪播放工具
  3. 达人评测锐龙r7 6850u和 R7 6850HS选哪个好
  4. 输出重定向Linux命令,Linux Shell重定向(输入输出重定向)精讲
  5. 在CMD中运行java程序
  6. 三星手机换新卡显示无服务器,玩机“老炮”告诉你三星手机新玩法
  7. day01-网络爬虫
  8. origin账号能买吗_一名Origin用户价值上万的游戏账号被莫名删除 EA客服起初竟拒绝帮他找回丢失的账号...
  9. 一周日期选择(周一至周日)
  10. Java8 日期、时间骚操作