读书人

java分布式开发TCP/IP NIO无拥塞 Sock

发布时间: 2012-11-01 11:11:32 作者: rapoo

java分布式开发TCP/IP NIO无阻塞 Socket((基于消息方式实现系统间的通信) )

在java中可以基于java.nio.channels中的Channel和Selector的相关类来实现TCP/IP+NIO方式的系统间通信。

?

用于系统间通信依靠SocketChannel和ServerSocketChannel,SocketChannel用于建立连接,监听事件及操作读写,ServerSocketChannel用于监听端口及监听连接事件,可通过Selector来获取是否有要处理的事件。

?

服务端java代码:

package com.java.distributed.message.tcpip;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.InetSocketAddress;import java.net.SocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.SocketChannel;import java.nio.charset.Charset;public class NIOClient {/** * @param args * @throws IOException  */public static void main(String[] args) throws IOException {int port =7889;SocketChannel channel=SocketChannel.open();channel.configureBlocking(false);SocketAddress target=new InetSocketAddress("127.0.0.1",port);channel.connect(target);Selector selector=Selector.open();//用于套接字连接操作的操作集位channel.register(selector, SelectionKey.OP_CONNECT);BufferedReader systemIn=new BufferedReader(new InputStreamReader(System.in));while(true){if(channel.isConnected()){String command=systemIn.readLine();channel.write(Charset.forName("UTF-8").encode(command));if(command==null||"quit".equalsIgnoreCase(command.trim())){systemIn.close();channel.close();selector.close();System.out.println("Client quit !");System.exit(0);}}int nKeys=selector.select(1000);if(nKeys>0){for(SelectionKey key:selector.selectedKeys()){if(key.isConnectable()){SocketChannel sc=(SocketChannel) key.channel();sc.configureBlocking(false);sc.register(selector, SelectionKey.OP_READ);sc.finishConnect();}else if(key.isReadable()){ByteBuffer buffer=ByteBuffer.allocate(1024);SocketChannel sc=(SocketChannel) key.channel();int readBytes=0;try{int ret=0;try{while((ret=sc.read(buffer))>0){readBytes+=ret;}}finally{buffer.flip();}if (readBytes > 0) {                                   System.out.println(Charset.forName("UTF-8")                                           .decode(buffer).toString());                                   buffer = null;                               }   }finally {                               if (buffer != null) {                                   buffer.clear();                               }}}}selector.selectedKeys().clear();   }}}}

?

1 楼 mars914 2011-11-07 channel,Buffer,selector。Java 标准IO中基于流进行数据交互,java NIO中给出了许多Buffer,基于数据块进行操作,通过channel(通道)进行交互。Channel同时支持异步的读和写。且主要与buffer进行数据读写。

Selector也是Java NIO提供的类,能够监听网络IO中Channel的事件,检查Channel是否准备好可读/可写,以及连接(connect),accept。一个Selector可支持监听多个Channel的事件。这样NIO中可以一个线程可以支持多个请求发送。

同样,考虑客户端发送多个请求,NIO方式相比BIO可以做到不阻塞,因此客户端可以采用连接复用的方式,即每个SocketChannel在发送消息后,不用等待响应可继续发送其他消息。这样可以降低连接池带来的资源争抢问题,对系统性能有帮助。

对于服务器接受多个连接请求,通常采用的是有一个线程来监听连接事件,另一个线程来监听网络流的读写事件。

当有网络流的读写事件时,在放入一个线程池中处理。这种方式比TCP/IP+BIO的好处是在于可接受很多连接,而这些连接只有在有真正的与服务器进行(请求)交互才会创建线程进行处理。这网上被称为:一请求一连接。

当连接数不多,或者连接数很多而且连接上的请求比较频繁是,TCP/IP NIO方式不会带相比TCP/IP+BIO理论上不会有太大的优势。

综上,TCP/IP+NIO对于高访问量的系统来说,服务器端可以支撑更多的连接。

读书人网 >编程

热点推荐