原文链接:http://tutorials.jenkov.com/java-nio/buffers.htmlJava NIO Buffers用于和NIO Channel交互。正如你已经知道的,我们从channel中读取数据到buffers里,从buffer把数据写入到channels.buffer本质上就是一块内存区,可以用来写入数据,并在稍后读取出来。这块内存被NIO Buffer包裹起来,对外提供一系列的读写方便开发的接口。
原文链接:http://tutorials.jenkov.com/java-nio/channels.htmlJava NIO Channel通道和流非常相似,主要有以下几点区别:通道可以读也可以写,流一般来说是单向的(只能读或者写)。通道可以异步读写。通道总是基于缓冲区Buffer来读写。正如上面提到的,我们可以从通道中读取数据,写入到buffer;也可以中buffer内读数据,写入到通道中。
原文链接:http://tutorials.jenkov.com/java-nio/overview.htmlNIO包含下面几个核心的组件:ChannelsBuffersSelectors整个NIO体系包含的类远远不止这几个,但是在笔者看来Channel,Buffer和Selector组成了这个核心的API。其他的一些组件,比如Pipe和FileLock仅仅只作为上述三个的负责类。因此在概览这一节中,会重点关注这三个概念。
原文链接:http://tutorials.jenkov.com/java-nio/index.htmlJava NIO是java 1.4之后新出的一套IO接口,这里的的新是相对于原有标准的Java IO和Java Networking接口。NIO提供了一种完全不同的操作方式。NIO中的N可以理解为Non-blocking,不单纯是NewJava NIO: Channels and Buffers标准的IO编程接口是面向字节流和字符流的。
在查阅NIO相关资料时, 发现一份很不错的资源,一位老外写的nio系列教程:http://tutorials.jenkov.com/java-nio/index.html通读的过程中发现作者的文笔非常好,把技术概念讲的透彻,浅显易懂。教程质量整体非常不错?,故而将其翻译为中文版?。 翻译系列暂定名为《Java NIO 简明教程》。版本修订时间v1.02016/05/11v1.12016/07/07v1.
建立 TCP 连接新的 Socket 实例创建后,就立即能用于发送和接收数据。也就是说,当 Socket 实例返回时,它已经连接到了一个远程终端,并通过协议的底层实现完成了 TCP 消息或握手信息的交换。客户端连接的建立Socket 构造函数的调用与客户端连接建立时所关联的协议事件之间的关系下图所示:当客户端以服务器端的互联网地址 W.X.Y.
基础准备首先需要明白数据传输的底层实现机制,在上一章中有详细的介绍,我们提到了 SendQ 和 RecvQ 缓冲队列,这两个缓冲区的容量在具体实现时会受一定的限制,虽然它们使用的实际内存大小会动态地增长和收缩,但还是需要一个硬性的限制,以防止行为异常的程序所控制的单一 TCP 连接将系统的内存全部消耗。
底层数据结构如果不理解套接字的具体实现所关联的数据结构和底层协议的工作细节,就很难抓住网络编程的精妙之处,对于 TCP 套接字来说,更是如此。套接字所关联的底层的数据结构集包含了特定 Socket 实例所关联的信息。比附,套接字结构除其他信息外还包含:该套接字所关联的本地和远程互联网地址和端口号。
NIO 主要原理及使用NIO 采取通道(Channel)和缓冲区(Buffer)来传输和保存数据,它是非阻塞式的 I/O,即在等待连接、读写数据(这些都是在一线程以客户端的程序中会阻塞线程的操作)的时候,程序也可以做其他事情,以实现线程的异步操作。
简介Java NIO 从 JDK1.4 引入,它提供了与标准 IO 完全不同的工作方式。NIO 包(java.nio.*)引入了四个关键的抽象数据类型,它们共同解决传统的 I/O 类中的一些问题。Buffer:它是包含数据且用于读写的线形表结构。其中还提供了一个特殊类用于内存映射文件的 I/O 操作。Charset:它提供 Unicode 字符串影射到字节序列以及逆影射的操作。
示例在第一章中,作者给出了一个 TCP Socket 通信的例子——反馈服务器,即服务器端直接把从客户端接收到的数据原原本本地反馈回去。示例客户端代码如下:import java.net.Socket; import java.net.SocketException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream;
线程池在 Java TCP Socket 编程这篇文章中,服务器端采用的实现方式是:一个客户端对应一个线程。但是,每个新线程都会消耗系统资源:创建一个线程会占用 CPU 周期,而且每个线程都会建立自己的数据结构(如,栈),也要消耗系统内存,另外,当一个线程阻塞时,JVM 将保存其状态,选择另外一个线程运行,并在上下文转换(context switch)时恢复阻塞线程的状态。
在传输消息时,用 Java 内置的方法和工具确实很用,如:对象序列化,RMI 远程调用等。但有时候,针对要传输的特定类型的数据,实现自己的方法可能更简单、容易或有效。下面给出一个实现了自定义构建和解析协议消息的 Demo。该例子是一个简单的投票协议。这里,一个客户端向服务器发送一个请求消息,消息中包含了一个候选人的 ID,范围在 0~1000。
程序间达成的某种包含了信息交换的形式和意义的共识称为协议,用来实现特定应用程序的协议叫做应用程序协议。大部分应用程序协议是根据由字段序列组成的离散信息定义的,其中每个字段中都包含了一段以位序列编码(即二进制字节编码,也可以使用基于文本编码的方式,但常用协议如:TCP、UDP、HTTP 等在传输数据时,都是以位序列编码的)的特定信息。
UDP 的 Java 支持UDP 协议提供的服务不同于 TCP 协议的端到端服务,它是面向非连接的,属不可靠协议,UDP 套接字在使用前不需要进行连接。实际上,UDP 协议只实现了两个功能:在 IP 协议的基础上添加了端口;对传输过程中可能产生的数据错误进行了检测,并抛弃已经损坏的数据。
TCP 的 Java 支持协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP 协议族有 IP 协议、TCP 协议和 UDP 协议。现在 TCP/IP 协议族中的主要 socket 类型为流套接字(使用 TCP 协议)和数据报套接字(使用 UDP 协议)。 TCP 协议提供面向连接的服务,通过它建立的是可靠地连接。
协议简介协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析。TCP/IP 协议族有 IP 协议、TCP 协议和 UDP 协议。TCP 协议和 UDP 协议使用的地址叫做端口号,用来区分同一主机上的不同应用程序。
本书由浅入深,全面讲解了 Java Socket 方面的网络编程知识,包括 TCP、UDP、自定义协议、协议成帧、解析、多线程、线程池、NIO、死锁、Socket 套接字的底层实现机制等。通过本书的学习,能够让读者了解通过 Socket 技术实现服务器与客户端的通信,全面了解 Java 网络编程中的技术难点。适用人群本书适合作为 Java Socket 编程的入门教程,可供从事网络编程的技术人员参考。
以下是一些建议,当你的代码库日益壮大或者应用需要规划时可以参考。阅读源代码Werkzeug ( WSGI )和 Jinja (模板)是两个被广泛使用的工具,而 Flask 起源就是 用于展示如何基于这两个工具创建你自己的框架。随着不断地开发, Flask 被越来越多 的人认可了。当你的代码库日益壮大时,不应当仅仅是使用 Flask ,而更应当理解它。 阅读 Flask 的源代码吧。
Flask 应用可以采用多种方式部署。在开发时,你可以使用内置的服务器,但是在生产环境 下你就应当选择功能完整的服务器。下面为你提供几个可用的选择。除了下面提到的服务器之外,如果你使用了其他的 WSGI 服务器,那么请阅读其文档中与使用 WSGI 应用相关的部分。因为 Flask 应用对象的实质就是一个 WSGI 应用。
关注时代Java