Chinaunix首页 | 论坛 | 博客
  • 博客访问: 137088
  • 博文数量: 20
  • 博客积分: 434
  • 博客等级: 下士
  • 技术积分: 249
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-05 15:49
文章分类

全部博文(20)

文章存档

2011年(20)

我的朋友

分类: Java

2011-11-21 15:10:00

注意:
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 服务器
 * 说明:
 * 
 * 创建时间: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你好!
阅读(1366) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~