java nio socket server

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;

import config.ServerConfig;

/**
 * NIO 非阻塞 服务器
 * @author zhangzuoqiang
 * <br/>Date: 2011-3-5
 */
public class NIOServer {
	
	public static void main(String[] args) throws Exception{
		// 创建本地Socket信道.并设为非阻塞方式
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.socket().bind(new InetSocketAddress(ServerConfig.LISTENNING_PORT));
        serverChannel.configureBlocking(false);
        
        // 创建选择器(异步 I/O 中的核心对象),并将其注册到serverChannel
        Selector selector = Selector.open();
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);//监听 accept 事件
        
        while (true) {
        	if (selector.select(ServerConfig.CONNECT_TIMEOUT) == 0) {
        		 System.out.println("waiting...");
                 continue;
			}
        	
        	// 获得就绪信道的键迭代器
            Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();
            
            // 使用迭代器遍历就绪信道
            while (keyIter.hasNext()) {
            	 SelectionKey key = keyIter.next();
            	// 若有客户端连接,则准备一个clientChannel与之通信
    			if (key.isAcceptable()) {
    				SocketChannel clientChannel = ((ServerSocketChannel)key.channel()).accept();
                    clientChannel.configureBlocking(false);
                    clientChannel.register(key.selector(), SelectionKey.OP_READ, ByteBuffer.allocate(ServerConfig.BUFFER_SIZE));
    			}
    			
    			try {
    				// 客户端有写入时
        			if (key.isReadable()) {
        				// 获得与客户端通信的信道
                        SocketChannel clientChannel = (SocketChannel)key.channel();
                        // 得到并重置缓冲区的主要索引值
                        ByteBuffer buffer = (ByteBuffer)key.attachment();
                        buffer.clear();
                        // 读取信息获得读取的字节数
                        long bytesRead = clientChannel.read(buffer);
                        if(bytesRead == -1){// 没有读取到内容的情况
                        	clientChannel.close();
                        }else{
                        	// 将缓冲区准备为数据传出状态
                            buffer.flip();
                            
                            // 将获得字节字符串(使用Charset进行解码)
                            String receivedString = Charset.forName(ServerConfig.LOCAL_CHARSET).newDecoder().decode(buffer).toString();
                            System.out.println("接收到信息:" + receivedString);
                            
                            //接收到客户端的请求之后,将策略文件发送出去
                            if(receivedString.indexOf("<policy-file-request/>") >=0){
                            	String policyStr = ServerConfig.POLICY_XML + "\0";
                            	buffer = ByteBuffer.wrap(policyStr.getBytes(ServerConfig.LOCAL_CHARSET));
                            	clientChannel.write(buffer);
                            }
                            
                            // 准备发送的文本
                            String sendString = "你好,客户端. 已经收到你的信息" + receivedString;
                            // 将要发送的字符串编码(使用Charset进行编码)后再进行包装
                            buffer = ByteBuffer.wrap(sendString.getBytes(ServerConfig.LOCAL_CHARSET));
                            // 发送回去
                            clientChannel.write(buffer);
                            
                            // 设置为下一次读取或是写入做准备
                            key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
                          }
        			}
				} catch (Exception e) {
					// TODO: 当客户端在读取数据操作执行之前断开连接会产生异常信息
					e.printStackTrace();
                    //将本socket的事件在选择器中删除
                    key.cancel();
                    break;
				}finally{
					// 删除处理过的 SelectionKey
	    			keyIter.remove();
				}    			
    		}
		}
        
	}
}
 

你可能感兴趣的:(java,.net,xml,socket)