先来看看我们的server端:

  创建一个serversocket,进行监听,每来一个客户端,就启动一个新启动为其服务:

  private void createListenSocket() {

  //如果创建监听socket的时候发生异常,将会隔WAIT_TIME毫秒重试,直到成功

  while (true){

  try {

  serverSocket = new ServerSocket(LISTEN_PORT);

  Log.info(创建监听socket成功,正在监听...);

  break;

  } catch (IOException e) {

  Log.error(创建监听socket失败,原因:+e.getMessage()+WAIT_TIME+ms后重建);

  ThreadUtils.sleep(WAIT_TIME);

  }

  }

  }

  private void listen() throws IOException {

  Socket socket = null;

  //启动一个死循环来监听连接本服务器的socket

  while ((socket = server.accept()) != null) {

  // 来访客户记录到服务器:

  Destination destination = new Destination();

  destination.setSocket(socket);

  server.newDestination(destination);

  //启动一条子线程来处理连接本服务器的socket消息收发

  new SubListenThread(destination,server).start();

  }

  }

  以上代码来自我半年前编写的一个远控程序服务端。在这个模型当中,服务端线程与客户端线程是1:1的关系,也就是说有多少个客户端,服务端就得创建多少个线程。

  在java当中,创建线程的代价是很大的。如果有几千个客户端,这个程序是撑不住的。

  那么像旺旺这种在线量可以达到几百万的应用,在单个机器上,势必要用一种比BIO更好的编程模型来实现。

  那么NIO就可以解决这种应用场景。

  关于NIO的教程,网上有非常多的详细教程,在这里就不赘述。就简单说说NIO编程模型:

  首先,我们有几个基本概念:

  1.channel 大家可以把它想象成stream,只不过我们可以通过channel进行双工通信,也就是能读又能写。

  2.buffer 可以看做是一段缓存,我们能通过这么一段缓存对channel进行读写。

  3.selector 中文直接翻译过来就是选择器,因为在NIO当中,我们不通过传统的一个线程处理一个客户端,而是通过轮询的方式知道哪些客户端可读、可连接,从而实现1:n的模型。

  那么NIO的编程模型如下:

  通过一个selector,客户端会连接到这个selector,我们可以通过一个死循环不断地轮询selector有哪些客户端,然后一旦监听到可读或者可连接事件,我们就进行相应的业务逻辑处理,该读读,该写写。

  以下为一个简单多人聊天室部分源码:

  

  

  看起来还是很复杂的,至少比传统的BIO通信模型复杂。

  使用原生的nio api进行编程很难,而且这玩意还有bug,据说在1.8以上版本仍存在空轮询BUG,会让CPU飙到100%。

  所以说,如果可以的话,尽量使用一些第三方框架,比如netty。

谈谈传统BIO网络编程模型的局限性与NIO的更多相关文章

  1. Linux IO模型和网络编程模型

    术语概念描述: IO有内存IO.网络IO和磁盘IO三种,通常我们说的IO指的是后两者. 阻塞和非阻塞,是函数/方法的实现方式,即在数据就绪之前是立刻返回还是等待. 以文件IO为例,一个IO读过程是文件 ...

  2. Java网络编程和NIO详解3:IO模型与Java网络编程模型

    Java网络编程和NIO详解3:IO模型与Java网络编程模型 基本概念说明 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32 ...

  3. linux网络编程模型

    1.编程模型 Linux网络编程模型是基于socket的编程模型

  4. [国嵌攻略][090][linux网络编程模型]

    编程模型 Socket的实质就是一个接口,利用该接口,用户在使用不同的网络协议时,操作函数得以统一.而针对不同协议的差异性操作,则交给了Socket去自行解决. TCP编程模型 UDP编程模型

  5. 【网络编程】Socket套接字网络编程模型

    一.Linux网络模型 -- Socket套接字编程 图片:Socket 抽象层 Socket编程--不同协议,统一接口 Socket的实质就是一个接口, 利用该接口,用户在使用不同的网络协议时,操作 ...

  6. 网络编程模型(C/S模型和B/S模型)

    目录 网络应用编程模型 互联网与企业内部网 早期计算机网络的通信模型 C/S模式 B/S模式 B/S 和 C/S 的区别 网络应用编程模型 互联网与企业内部网 网络的两个含义: 互联网 :互联网(In ...

  7. 谈谈c#中异步编程模型的变迁

    大家在编程过程中都会用到一些异步编程的情况.在c#的BCL中,很多api都提供了异步方法,初学者可能对各种不同异步方法的使用感到迷惑,本文主要为大家梳理一下异步方法的变迁以及如何使用异步方法. Beg ...

  8. iOS网络编程模型

    iOS网络编程层次结构也分为三层: Cocoa层:NSURL,Bonjour,Game Kit,WebKit Core Foundation层:基于 C 的 CFNetwork 和 CFNetServ ...

  9. 网络编程模型及TCP、UDP编程设计

    1.Linux网络模型 Linux网络编程--->>>socket套接字的编程 2.TCP网络模型                                          ...

随机推荐

  1. Spark SQL 编程初级实践

    一.实验目的 (1)       通过实验掌握 Spark SQL 的基本编程方法: (2)       熟悉 RDD 到 DataFrame 的转化方法: (3)       熟悉利用 Spark ...

  2. SpringMVC常见面试题总结

    1.什么是Spring MVC ?简单介绍下你对springMVC的理解? Spring MVC是一个基于MVC架构的用来简化web应用程序开发的应用开发框架,它是Spring的一个模块,无需中间整合 ...

  3. C# 将文件夹中文件复制到另一个文件夹

    p{ text-align:center; } blockquote > p > span{ text-align:center; font-size: 18px; color: #ff0 ...

  4. html5 css多列布局

    p{    text-indent: 2em;    line-height: 2em;}h4{    -webkit-column-span:all;    background: green;   ...

  5. httpd 处理模型

    prefork 一个请求用一个进程响应 worker 一个请求用一个线程响应(启动多个进程,多个进程生成多个线程) event 一个进程,处理多个请求

  6. linux 扩展文件系统

    1. 创建新分区 [root@localhost ~]# fdisk -l Disk /dev/sda: bytes, sectors Units = sectors of * = bytes Sec ...

  7. git 本地提交代码到 github 远程库,没有弹框 github login

     git 本地提交代码到 github 远程库,没有弹框 github login:  原因: win10 有个凭据管理器,给保存了历史登陆用户名密码,导致无法切换用户. 解决办法: 删除历史登陆用户 ...

  8. [转载]URL 源码分析

    URI 引用包括最多三个部分:模式.模式特定部分和片段标识符.一般为: 模式:模式特定部分:片段 如果省略模式,这个URI引用则是相对的.如果省略片段标识符,这个URI引用就是一个纯URI. URI是 ...

  9. Docker 构建 RabbitMQ 集群

    刚开始,关于RabbitMQ集群的搭建,我找到了这篇文章:Docker 安装 RabbitMQ 集群 从而找到了第三方的RabbitMQ集群容器 rabbitmq-server 但是这个容器只有3.6 ...

  10. fastjson的简单使用

    实习初期,开始接触到系统的后台日志查询展示到前台,后台将查询到的数据转化成json格式返回前台,发现系统使用的是阿里的fastjson,于是想来了解一下fastjson的使用. 以下使用都是基于这个版 ...