一  基本概念
  1. IO(BIO)和NIO的区别:其本质就是阻塞和非阻塞的区别。
阻塞:应用程序在获取网络数据的时候,如果网络传输数据很慢,那程序就一直等着,直到传输完毕为止。
非阻塞:应用程序直接可以获取已经准备就绪的数据,无需等待。
IO为同步阻塞形式,NIO为同步非阻塞,到JDK1.7,NIO为异步非阻塞。
同步是指应用程序直接参与IO读写;异步是指操作系统操作IO,应用程序直接取结果。
同步说的是server服务器端的执行方式; 阻塞说的是具体的技术,接受数据的方式。
  1. NIO基于Buffer(缓冲区)、Channel(管道)、Selector(选择器)。
2.1 Buffer:实质上是一个数组,它为缓冲区提供了数据操作的概念,如位置、容量等。除Boolean外,每一种java基本类型都对应了一种缓冲区。
2.2 Channel:类似水管,网络数据通过Channel读取和写入。
通道是双向的,流是单向的。
通道可用于读、写或两者同时进行。
通道可以与多路复用器结合,有多种状态位,方便多路复用器识别。
通道分为两大类:网络读写(SelectableChannel);
文件操作(FileChannel);
3. Selector:多路复用器(selector),他是NIO编程的基础,非常重要。多路复用器提供选择已经就绪的任务的能力。

  简单说,就是selector会不断地轮询注册在其上的通道(channel),如果某个通道发生了读写操作,这个通道就处于就绪状态,会被selector轮询出来,然后通过selectionKey可以取得就绪的channel集合,从而进行后续的IO操作。
  一个多路复用器(selector)可以负责成千上万channel通道,没有上限,这也是JDK使用了epoll代替了传统的select实现,获取连接句柄没有限制。这也就意味着我们只要一个线程负责selector的轮询,就可以接入成千上万个客户端,这就是JDK NIO库的巨大进步。

  (扩展——Epoll是什么:epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。epoll除了提供select/poll那种IO事件的水平触发(Level Triggered)外,还提供了边缘触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少epoll_wait/epoll_pwait的调用,提高应用程序效率。)

  selector线程就类似一个管理者(master),管理成千上万个管道,然后轮询哪个管道的数据已经准备好,通知cpu执行IO的读取或写入操作。
selector模式:当IO事件(管道)注册到选择器以后,selector会分配给每个管道一个key值,相当于标签。selector选择器是以轮询的方式进行查找注册的所有IO事件(管道),当我们的IO事件(管道)准备就绪后,select就会识别,会通过key值来找到相应的管道,进行相关的数据处理操作(从管道里读或写数据,写到我们的数据缓冲区中)。
每个管道都会对选择器进行注册不同的事件状态,以便选择器查找。

  SelectionKey.OP_CONNECTSelectionKey.OP_ACCEPTSelectionKey.OP_READSelectionKey.OP_WRITE

面试常问:Bio——NIO——AIO区别和进化过程

二  Netty
简单强大的NIO框架,异步。可以快速开发网络应用,如服务器和客户端协议。简单实现点我参考。
1、TCP粘包、拆包问题

  熟悉tcp编程的可能都知道,无论是服务器端还是客户端,当我们读取或者发送数据的时候,都需要考虑tcp底层的粘包/拆包机制。
  tcp是一个“流”协议,所谓流就是没有界限的一串数据。大家可以想象下如果河里的水就好比数据,他们是连成一片的,没有分界线。tcp底层并不了解上层的业务数据具体的含义,它会根据tcp缓冲区的实际情况进行包的划分,也就是说,在业务上,我们一个完整的包可能会被tcp分成多个包进行发送,也可能把多个小包封装成一个大的数据包发送出去,这就是所谓的tcp粘包、拆包问题。分析tcp粘包、拆包问题的产生原因
    1.应用程序write写入的字节大小大于套接口发送缓冲区的大小
    2.进行MSS大小的TCP分段
    3.以太网帧的payload大于MTU进行IP分片

  拆包的三种解决方案
    1.消息定长,例如每个报文的大小固定为200个字节,如果不够,空位补空格。
    2.在包尾部增加特殊字符进行分割,例如加回车等。
    3.将消息分为消息头和消息体,在消息头中包含表示消息总长度的字段,然后进行业务逻辑的处理

  拆包具体实现可以用两个类
    1.分隔符类:DelimiterBasedFrameDecoder(自定义分隔符)
    2.FixedLengthFrameDecoder(定长)

2、Netty编解码技术
      编解码技术,说白了就是Java序列化技术,序列化目的就两个,第一是进行网络传输,第二是对象持久化。
      虽然我们可以使用Java进行对象序列化,netty去传输,但是Java序列化的硬伤太多,比如Java序列化没法跨语言、序列化后码流太大、序列化性能太低等等
      主流的编解码框架:
        JBoss的Marshalling包(是一个Java对象序列化包,对JDK默认的序列化框架进行了优化,又保持了跟java.io.serializable接口的兼容,同时增加了一些可调参数,与netty结合后进行序列化对象的代码编写很简单)
        google的protobuf
        基于protobuf的Kyro
        MessagePack框架

3、Netty主要应用场景

  1.数据通信  

    两台及以上机器如何使用netty通信:
      1.使用长连接通道不断开的形式进行通信,也就是服务器和客户端的通道一直处于开启状态,如果服务器性能够好,并且客户端数量也比较少的情况下,推荐此方式。
      2.一次性批量提交数据,采用短连接方式。也就是我们会把数据保存在本地临时缓冲区或者临时表里,当达到临界值时进行一次性批量提交,又或者根据定时任务轮询提交,这种情况的弊端是做不到实时传输,对实时性要求不高的应用程序中可以推荐使用。
      3.我们可以使用一种特殊的长连接,在指定某一段时间之内,服务器与某台客户端没有任何通信,则断开连接。下次连接则是客户端向服务器发送请求的时候,再次建立连接。这种模式需要考虑两个因素,
        3.1如何在超时(即服务器和客户端没有任何通信)后关闭通道,关闭后又该如何再次建立连接
        3.2客户端宕机时,我们不用管,下次客户端重启之后我们就可以与服务器建立连接,但当服务器宕机时,我们的客户端如何与服务器进行连接

  2.心跳测试

    我们使用socket通信一般会经常处理多个服务器之间的心跳检测,一般服务器集群,会有一台或多台主机(master),和多台从机(slave),那么主机肯定要时时刻刻知道自己下面的从机的各方面情况,然后进行实时监控的功能,这个在分布式架构里叫做心跳检测或心跳监控。最佳处理方案还是使用一些通信框架进行实现,如netty。

  3.文件上传下载

附:Mina是一个和netty类似的框架,它属于Apache。

Java网络通信编程从基础到框架相关推荐

  1. Java程序员从笨鸟到菜鸟之(十三)java网络通信编程

    首先声明一下,刚开始学习Java网络通信编程就对他有一种畏惧感,因为自己对网络一窍不通,所以...呵呵..你懂得,昨天又仔细的学习了一遍,感觉其实java网络编程也没想象的那么难,不信,咱一起看看.. ...

  2. 学习笔记:Java 并发编程①_基础知识入门

    若文章内容或图片失效,请留言反馈. 部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 视频链接:https://www.bilibili.com/video/av81461839 视频下载: ...

  3. Java编程语言学习:Java语言编程的基础知识之Java的变量与数据类型、符号、运算符、数组Array总结之详细攻略

    Java编程语言学习:Java语言编程的基础知识之Java的变量与数据类型.符号.运算符.数组Array总结之详细攻略 目录 Java语言编程的基础知识之Java的变量与数据类型.符号.运算符.数组总 ...

  4. Java并发编程实战基础概要

    文章目录 Java并发编程实战基础概要 开篇 多线程问题有啥难点呢? 为啥要学习并发编程? 并发问题的根源是什么? CPU切换线程执导致的原子性问题是如何发生的? 缓存导致的可见性问题是如何发生的? ...

  5. Java网络编程(网络基础(IP端口号网络通信协议)、TCP编程、UDP编程和URL编程原理以及常用方法的实例)

    网络编程 网络基础概述 计算机网络:   把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大.功能强的网络系统,从而使众多的计算机可以方便地互相传递信息.共享硬件.软件.数据信息等 ...

  6. java多线程基础视频_【No996】2020年最新 Java多线程编程核心基础视频课程

    01.课程介绍.mp4 02.多线程编程基础-进程与线程.mp4 03.多线程编程基础-使用多线程-继承Thread类.mp4 04.多线程编程基础-使用多线程-实现Runnable接口.mp4 05 ...

  7. JAVA并发编程的基础

    1.线程简介 什么是线程? 操作系统在运行一个程序时,会为其创建一个进程. 线程是操作系统调度的最小单元,也叫轻量级进程. 在一个进程里可以创建多个线程,这些线程拥有各自的计数器.堆栈和局部变量等属性 ...

  8. java并发编程艺术——基础篇

    这篇文章目的是为了总结一下这段时间看<java并发编程艺术>学到的东西,尝试用自己的话说出来对java多线程的理解和使用. 一.什么是多线程,为什么要用多线程,多线程带来的挑战 多线程定义 ...

  9. JAVA并发编程JUC基础学习(简介)

    2019独角兽企业重金招聘Python工程师标准>>> 之前写过一篇并发编程的简单实例应用,Future快速实现并发编程,可以很快的在自己的项目中应用,但并不系统,之前说过总结一篇( ...

最新文章

  1. 怎么把python结果全部显示-python – 如何展开输出显示以查看更多列?
  2. python安装pyquery失败
  3. 百斗度输入法linux,斗字输入法安卓版-斗字输入法app下载-最火软件站
  4. js技巧之与或运算符 || 妙用
  5. 使用Datastax Java驱动程序与Cassandra进行交互
  6. spring cloud(二)
  7. 黄聪:360浏览器、chrome开发扩展插件教程(1)开发Chrome Extenstion其实很简单
  8. 爬虫 知识点 总结。
  9. python web框架的基础:WSGI、uWSGI、Nginx、web框架的关系
  10. 寻找 IT 服务行业隐形冠军, 航天信息上市十年再造中国梦
  11. bit、Byte、KB、MB、GB互相转换的关系
  12. “决策树”——数据挖掘、数据分析
  13. 全国省市县sql(完整版)
  14. 3. 自定义Java编译时注解处理器
  15. 邻接矩阵的存储方式实现图的广度和深度优先遍历
  16. css li修改小圆点的颜色
  17. 学习java第6天 模仿XP画板(10%)
  18. Electron源码学习: Electron组成与初始化流程
  19. 一个工程师对潘多拉开发板的使用体验
  20. BIM模型文件下载——某教学楼项目Revit模型

热门文章

  1. Linux 环境边配置边学(针对家里电脑) 【五】
  2. sql时间小问题汇总
  3. 2007 Office System Video
  4. springboot租房管理系统答辩PPT模板
  5. 和quicklook相似的软件_细数软件推荐上万热度出现比例较高的10款软件,看看谁出现最多...
  6. oracle dba 两日速成课程.pdf,oracle_dba_两日速成课程.pdf
  7. python比较两个列表的重合度_#源代码#超几何分布算法介绍及python下的实现代码...
  8. c语言编辑学生信息录入的程序,c语言编的学生信息管理系统小程序!!有不足的请指出,谢谢!!...
  9. oracle 11g regexp_substr,oracle中REGEXP_SUBSTR方法的使用
  10. oracle大黑点,R语言实现交通行业事故案例之黑点确定 - 数据分析