导读

网络通信包含两部分:网络协议和IO

网络协议包括:TCP/IP,UDP/IP和Multicast

IO包括:同步IO(NIO/BIO)和异步IO(AIO)

上边的部分都是作为Java分布式应用的基础,目前用于系统间通信的可以大致分为两类:基于消息方式实现系统间的通信、远程调用方式的系统间通用。

基于消息方式实现系统间的通信就是使用基本的jdk操作Socket来实现系统间的通信,而远程调用方式的实现我们可以通过目前主流框架和系统提供的服务。

基于消息方式实现系统间的通信

1、TCP/IP

TCP/IP是一种可靠的网络数据传输的协议。TCP/IP要求通信双方首先建立连接,之后再进行数据的传输。

TCP/IP负责保证数据传输的可靠性,包括数据的可到达、数据到达的顺序等,但由于TCP/IP需要保证连接及数据传输的可靠,因此可能会牺牲一些性能。

2、UDP/IP

UDP/IP是一种不保证数据一定到达的网络数据传输协议。UDP/IP并不直接给通信的双方建立连接,而是发送到网络上进行传递。由于UDP/IP不建立连接,并且不能保证数据传输的可靠,因此性能上表现相对较好,但可能会出现数据丢失以及数据乱序的现象。

3、同步IO和异步IO

TCP/IP和UDP/IP可用于完成数据的传输,是一种数据传输的协议规范,但要完成系统间通信,还需要对数据进行处理。例如读取和写入数据,按照POSIX标准分为同步IO和异步IO两种,其中同步IO中最常用的是BIO(Blocking IO)和NIO(Non-Blocking IO),异步IO是AIO

(1)BIO(阻塞模式)就是当发起IO的读或写操作时,均为阻塞方式,只有当程序读到了流或将流写入操作系统后,才会释放资源。

(2)NIO(非阻塞模式)是基于事件驱动思想的,实现上通常采用Reactor模式,从程序角度而言,当发起IO的读或写操作时,是非阻塞的;

当Socket有流可读或可写入Socket时,操作系统会相应地通知应用程序进行处理,应用再将流读取到缓冲区或写入操作系统。对于网络IO而言,主要有连接建立、流读取及流写入三种事件,Linux 内核版本在2.6以后的版本采用c方式来实现NIO。

(3)AIO(非阻塞)为异步IO方式,同样基于事件驱动思想,实现上通常采用Proactor模式。从程序角度而言,和NIO不同,当进行读写操作时,只须直接调用API的read或write方法即可,AIO和NIO均为异步的。

a)对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;

b)对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。

较之NIO而言,AIO一方面简化了程序的编写,流的读取和写入都由操作系统来代替完成;另一方面省去了NIO中程序要遍历事件通知队列(Selector)的代价。Windows基于IOCP实现了AIO,Linux目前只有基于epoll模拟实现的AIO

基于远程调用方式实现系统间的通信

Java对TCP/IP和UDP/IP均支持,在网络IO的操作上,Java 7以前的版本仅支持BIO和NIO两种方式,对AIO方式感兴趣的读者可自行下载Sun JDK 7进行尝试。

当系统之间要通信时,可通过调用本地的一个Java接口的方法,透明地调用远程的Java实现。具体的细节则由Java或框架来完成,这种方式在Java中主要用来实现基于RMI和WebService的应用。

本章通过举例来介绍如何基于Java的包及开源的产品来实现以上两种方式的系统间通信,这些是实现分布式Java应用的基础和必备知识,采用的例子如下。

示例程序由一个服务器端程序和一个客户端程序构成,是典型的请求-响应机制,即客户端发送请求,服务端响应。客户端读取用户的输入,并将输入的字符串信息发送给服务器端,服务器端接收到信息后响应,当客户端输入的是quit字符串时,则停止客户端和服务器端的程序。