Java NIO 服务器端简单实现例子

Java NIO 服务器端简单实现例子
注意:
1.NIO主要用于服务端,若用来客户端相对于它带来的额外复杂性有点不值得。
2.用于编码解码字符集请根据您的机器缺省字符集进行调整,如GB2312,GBK,UTF-8,UTF-16等,若出现乱码请更换之。
3.BufferSize请根据您可能发送接收的最大字符串长度进行相应调整。

代码:
package  com.heyang.biz.server.test.nio;

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;


/**
 * NIO 服务器
 * 说明:
 * 作者:何杨([email protected])
 * 创建时间:2011-1-3 下午12:09:02
 * 修改时间:2011-1-3 下午12:09:02
 
*/
public   class  NIOServer{
    
//  本地字符集
     private   static   final  String LocalCharsetName  =   " gb2312 " ;

    
//  本地服务器监听的端口
     private   static   final   int  Listenning_Port = 8888 ;
    
    
//  缓冲区大小
     private   static   final   int  Buffer_Size = 1024 ;
    
    
//  超时时间,单位毫秒
     private   static   final   int  TimeOut = 3000 ;
    
    
public   static   void  main(String[] args)  throws  Exception{
        
//  创建一个在本地端口进行监听的服务Socket信道.并设置为非阻塞方式
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.socket().bind(
new  InetSocketAddress(Listenning_Port));
        serverChannel.configureBlocking(
false );
        
        
//  创建一个选择器并将serverChannel注册到它上面
        Selector selector = Selector.open();
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        
        
while ( true ){
            
//  等待某个信道就绪
             if (selector.select(TimeOut) == 0 ){
                System.out.println(
" . " );
                
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(Buffer_Size));
                }
                
                
//  客户端有写入时
                 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(LocalCharsetName).newDecoder().decode(buffer).toString();
                      
                      
//  控制台打印出来
                      System.out.println( " 接收到信息: " + receivedString);
                      
                      
//  准备发送的文本
                      String sendString = " 你好,客户端. 已经收到你的信息 " + receivedString;
                      
                      
//  将要发送的字符串编码(使用Charset进行编码)后再进行包装
                      buffer = ByteBuffer.wrap(sendString.getBytes(LocalCharsetName));
                      
                      
//  发送回去
                      clientChannel.write(buffer);
                      
                      
//  设置为下一次读取或是写入做准备
                      key.interestOps(SelectionKey.OP_READ  |  SelectionKey.OP_WRITE);
                    }
                }
                
                keyIter.remove();
            }
        }
        
    }
}

与之配合的客户端代码,没有采用NIO方式。
package  com.heyang.biz.server.test.nio;

import  java.io.InputStream;
import  java.io.OutputStream;
import  java.io.PrintWriter;
import  java.net.Socket;
import  java.util.Scanner;



public   class  TestClient{
    
public   static   void  main(String[] args)  throws  Exception{
        Socket s
= new  Socket( " 127.0.0.1 " , 8888 );
        
        InputStream  inStram
= s.getInputStream();
        OutputStream outStream
= s.getOutputStream();
        
        
//  输出
        PrintWriter out = new  PrintWriter(outStream, true );
        
        out.print(
" getPublicKey你好! " );
        out.flush();

        s.shutdownOutput();
//  输出结束
        
        
//  输入
        Scanner in = new  Scanner(inStram);
        StringBuilder sb
= new  StringBuilder();
        
while (in.hasNextLine()){
            String line
= in.nextLine();
            sb.append(line);
        }
        String response
= sb.toString();
        System.out.println(
" response= " + response);
    }
}

服务器端的输出:
.
接收到信息:getPublicKey你好!
.

客户端的输出:
response=你好,客户端. 已经收到你的信息getPublicKey你好!

你可能感兴趣的:(Java NIO 服务器端简单实现例子)