在前面的章节里,我们讨论了Java NIO的基本概念,在这一节里,我们将结合具体的Java Socket编程,讨论使用NIO提高服务端程序的性能的问题。
Java NIO增加了新的SocketChannel、ServerSocketChannel等类来提供对构建高性能的服务端程序的支持。 SocketChannel、ServerSocketChannel能够在非阻塞的模式下工作,它们都是selectable的类。在构建服务器或者中间件时,推荐使用Java NIO。
在传统的网络编程中,我们通常使用一个专用线程(Thread)来处理一个Socket连接,通过使用NIO,一个或者很少几个Socket线程就可以处理成千上万个活动的Socket连接。
通常情况下,通过ServerSocketChannel.open()获得一个ServerSocketChannel的实例,通过SocketChannel.open或者serverSocketChannel.accept()获得一个SocketChannel实例。要使ServerSocketChannel或者SocketChannel在非阻塞的模式下操作,可以调用
serverSocketChannel.configureBlocking (false);
或者
socketChannel.configureBlocking (false);
语句来达到目的。通常情况下,服务端可以使用非阻塞的ServerSocketChannel,这样,服务端的程序就可以更容易地同时处理多个socket线程。
下面我们来看一个综合例子,这个例子使用了ServerSocketChannel、SocketChannel开发了一个非阻塞的、能处理多线程的Echo服务端程序,见示例12-14。
【程序源代码】
使用:运行此程序,然后在控制台输入命令telnet localhost 23。
【程序输出结果】如图12-1所示。
图12-1 输出结果
【程序注解】
关于程序的解释已经包含在程序里面了,在这里我们总结以下使用ServerSocket Channel开发服务端程序的过程:
(1)分配一个ServerSocketChannel。
(2)从ServerSocketChannel里获得一个对应的ServerSocket。
(3)生成一个Selector实例。
(4)把ServerSocket绑定到端口上。
(5)设置ServerSocketChannel为非block模式(可选)。
(6)在Selector里注册ServerSocetChannel。
(7)用一个无限循环语句始终查看Selector里是否有IO准备就绪的channel。如果有,就执行对应的处理,如果没有,继续循环。
小 结
在本章我们主要介绍了Java中的网络编程。Java一开始就是一种网络编程语言,到后来才应用到各个方面,所以在Java中进行网络编程远比在C/C++中方便。
我们介绍了几个在网络编程中很重要的类,如InetAddress、URL、URLConnection、Socket、 ServerSocket、DatagramSocket、DatagramPacket、MulticastSocket等。这些类包含了进行基本网络编程的所有内容。要熟练地应用这些类,关键还是要多多练习。
基于套接字的编程基本上是客户/服务器模式,我们具体介绍了编写这种模式的步骤。在实例方面,我们给出了一个基于TCP的套接字客户/服务器程序,与此相对应,还给出了基于UDP的客户/服务器程序。两者的模式是很相似的,其实这也就是编写客户/服务器程序的一般模式。 (T111)
Java NIO增加了新的SocketChannel、ServerSocketChannel等类来提供对构建高性能的服务端程序的支持。 SocketChannel、ServerSocketChannel能够在非阻塞的模式下工作,它们都是selectable的类。在构建服务器或者中间件时,推荐使用Java NIO。
在传统的网络编程中,我们通常使用一个专用线程(Thread)来处理一个Socket连接,通过使用NIO,一个或者很少几个Socket线程就可以处理成千上万个活动的Socket连接。
通常情况下,通过ServerSocketChannel.open()获得一个ServerSocketChannel的实例,通过SocketChannel.open或者serverSocketChannel.accept()获得一个SocketChannel实例。要使ServerSocketChannel或者SocketChannel在非阻塞的模式下操作,可以调用
serverSocketChannel.configureBlocking (false);
或者
socketChannel.configureBlocking (false);
语句来达到目的。通常情况下,服务端可以使用非阻塞的ServerSocketChannel,这样,服务端的程序就可以更容易地同时处理多个socket线程。
下面我们来看一个综合例子,这个例子使用了ServerSocketChannel、SocketChannel开发了一个非阻塞的、能处理多线程的Echo服务端程序,见示例12-14。
【程序源代码】
1 // ==================== Program Discription ===================== |
使用:运行此程序,然后在控制台输入命令telnet localhost 23。
【程序输出结果】如图12-1所示。
图12-1 输出结果
【程序注解】
关于程序的解释已经包含在程序里面了,在这里我们总结以下使用ServerSocket Channel开发服务端程序的过程:
(1)分配一个ServerSocketChannel。
(2)从ServerSocketChannel里获得一个对应的ServerSocket。
(3)生成一个Selector实例。
(4)把ServerSocket绑定到端口上。
(5)设置ServerSocketChannel为非block模式(可选)。
(6)在Selector里注册ServerSocetChannel。
(7)用一个无限循环语句始终查看Selector里是否有IO准备就绪的channel。如果有,就执行对应的处理,如果没有,继续循环。
小 结
在本章我们主要介绍了Java中的网络编程。Java一开始就是一种网络编程语言,到后来才应用到各个方面,所以在Java中进行网络编程远比在C/C++中方便。
我们介绍了几个在网络编程中很重要的类,如InetAddress、URL、URLConnection、Socket、 ServerSocket、DatagramSocket、DatagramPacket、MulticastSocket等。这些类包含了进行基本网络编程的所有内容。要熟练地应用这些类,关键还是要多多练习。
基于套接字的编程基本上是客户/服务器模式,我们具体介绍了编写这种模式的步骤。在实例方面,我们给出了一个基于TCP的套接字客户/服务器程序,与此相对应,还给出了基于UDP的客户/服务器程序。两者的模式是很相似的,其实这也就是编写客户/服务器程序的一般模式。 (T111)