欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 后台管理


新闻资讯

MENU

软件开发知识

Scattering与Gathering适用 CAD加密 于网络操作中的自定义协议

点击: 次  来源:宝鼎软件 时间:2017-09-10

原文出处: tomas家的小拨浪鼓

本文是笔者在进修NIO进程中发明的一些较量容易让人忽略的常识的一个总结,而这些让人忽略的小细节恰恰是NIO网络编程中必不行少。固然此刻我们不会直接编写NIO来完成我们的网络层通讯,而是利用成熟的基于NIO的网络框架来实现我们的网络层。如,netty、mina。但对NIO网络编程进程的相识,很是有助于我们更深入的领略netty、mina等网络框架,以至于能更好的利用它们。

因此,本文并差池NIO的一些下层常识做过多的先容,主要偏重于NIO编程中细节的讲授。

NIO VS IO

  • 尺度的IO基于字节约和字符流举办操纵的;而NIO是基于通道(Channel)举办操纵的。
  • 通道是双向的,既可以写数据到通道,又可以从通道中读取数据;而流的读写凡是是单向的,劳务派遣管理系统,要么是输入流,要么是输出流,不能既是输入流又是输出流。
  • NIO可以或许实现非阻塞的网络通信,而IO只能实现阻塞式的网络通信。
  • Buffer

    Java NIO中的Buffer用于和NIO通道举办交互。数据老是从通道读取到缓冲区,可能从缓冲区写入到通道中。
    Buffer是一个特定的原生范例数据容器。
    Buffer是一种特定的原生范例的线程的、有限的元素序列。除了它的内容之外,一个Buffer一个重要的本质属性是它的capacity、limit、和position;

  • capacity:一个buffer的capacity指的就是它所包括的元素的个数。buffer的capacity永远不会是负数,且永远不会变革。
  • limit:一个buffer的limit指的是不该该被读或写的第一个元素的索引( position <= limit )。一个buffer的limit永远不会是负数的,而且永远不会高出它的capacity。
  • position:一个buffer的position指的是下一个将要被读或写的元素的索引。一个buffer的position永远不会是负数的,而且永远不会高出它的limit( 这里也说明,position最多便是limit,当position==limit时,这个时候是不可以或许在从buffer中读取到数据了 )。
  • 数据操纵:

    Buffer的每一个子类都界说了两类get和put操纵。

  • 相对操纵:读或写 一个或多个元素 从当前position位置开始而且会按照转换元素数量增加position的值。假如要求的转换高出了limit,那么一个相关的get操纵会抛出BufferUnderflowException,一个相关的put操纵会抛出一个BufferOverflowException,无论是这两个哪种环境产生,都不会有数据被通报。
  • 绝对操纵:会接管一个显示元素的索引而且不会影响position。假如索引参数高出了limit,那么绝对的get和put操纵会抛出一个IndexOutOfBoundsException异常。
  • 稳定性:

    0 <= mark <= position <= limit <= capacity

    线程安详性:

    buffer在多线程并发下并不是安详的。假如一个buffer会在多个线程利用,那么需要利用得当的同步操纵来会见buffer。也就是buffer自己并不是线程安详的。

    Java NIO 内存分派

  • Heap buffer :仓库的内存分派。仓库就是Java内存模子傍边内存的区域,位于堆上,堆是我们生成工具的区域。
  • Direct buffer :堆外内存分派。这个内存自己不是由JVM举办节制的,它是由操纵系统举办统一的处理惩罚的。通过这种直接的缓冲就能实现zero-copy(零拷贝)的行动。 [ 关于堆外内存可详见:堆外内存 之 DirectByteBuffer 详解 ]
  • 要领

  • flip()
  • flip要领将Buffer从写模式切换到读模式。

  • rewind()
  • rewind()要领将position设回0,limit保持稳定,所以你可以重读Buffer中的所有数据。可见在挪用rewind()之前Buffer已经是处于读模式了

  • clear()
  • 让Buffer从头筹备好重头开始再次被写入。该要了解将position、limit重置。假如此时还没有读取的数据,则就无法读取到了。固然clear()不会清楚数据,可是position、limit符号位被重置了,所以无法找到哪些未读取数据的位置了。

  • compact()
  • compact()要领将所有未读的数据拷贝到Buffer起始处。然后将position设到最后一个未读元素正后头。limit属性依然像clear()要领一样,配置成capacity。此刻Buffer筹备好写数据了,可是不会包围未读的数据。

    clear() VS compact()

    clear只是对position、limit、mark举办重置,而compact在对position举办配置,以及limit、mark举办重置的同时,软件开发,还涉及到数据在内存中拷贝。所以compact比clear更耗机能。但compact能生存你未读取的数据,将新数据追加到为读取的数据之后;而clear则不可,若你挪用了clear,则未读取的数据就无法再读取到了。

  • Slice Buffer与原有buffer共享沟通的底层数据
  • ByteBuffer.slice(start, end) —————— [start, end),即包括start,不包括end
    slice返回的ByteBuffer底层数据和源ByteBuffer是共享的,所以无论对谁人buffer举办修改,城市影响到另一buffer。

  • buffer.asReadOnlyBuffer()