这个示例直接抄袭自某书,运行结果却不甚理想,请教诸位大虾
server 部分
package network;
import java.io.*;
import java.nio.channels.*;
import java.nio.*;
import java.nio.charset.*;
import java.net.*;
import java.util.*;
/**
 
 *
 */
public class EchoServer {
      
 /**
  * @param args
  */
  private Selector selector=null;
  private ServerSocketChannel serverSocketChannel=null;
  private int port=8000;
  private Charset charset=Charset.forName("GBK");
  
  public EchoServer() throws IOException{
   selector=Selector.open();
   serverSocketChannel=serverSocketChannel.open();
   serverSocketChannel.socket().setReuseAddress(true);
   serverSocketChannel.configureBlocking(false);
   serverSocketChannel.socket().bind(new InetSocketAddress(port));
   System.out.println("server start");
   
  }
  
  public void service()throws IOException{
   serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
   while(selector.select()>0){
    Set readyKeys=selector.selectedKeys();
    Iterator it=readyKeys.iterator();
    while(it.hasNext()){
     SelectionKey key=null;
     try{
      key=(SelectionKey) it.next();
      it.remove();
      
      if(key.isAcceptable()){
       ServerSocketChannel ssc=(ServerSocketChannel) key.channel();
       SocketChannel socketChannel=(SocketChannel) ssc.accept();
       System.out.println("receive connet from: "+socketChannel.socket().getIn
etAddress()+":"+socketChannel.socket().getPort());
       socketChannel.configureBlocking(false);
       ByteBuffer buffer=ByteBuffer.allocate(1024);
       socketChannel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_W
RITE,buffer);
      }
      if(key.isReadable()){
       receive(key);
      }
      if(key.isWritable()){
       send(key);
      }
     }
     catch(IOException e){
      e.printStackTrace();
      try{
       if(key!=null){
        key.cancel();
        key.channel().close();
       }
      }
      catch(Exception ex){e.printStackTrace();}
     }
    }
    
   }
   
  }
  public void send(SelectionKey key)throws IOException{
   ByteBuffer buffer=(ByteBuffer)key.attachment();
   SocketChannel socketChannel=(SocketChannel)key.channel();
   String data=decode(buffer);
   if(data.indexOf("\r\n")==-1)return;
   String outputData=data.substring(0, data.indexOf("\n")+1);
   System.out.print(outputData);
   ByteBuffer outputBuffer=encode("echo:"+outputData);
   while(outputBuffer.hasRemaining())
    socketChannel.write(outputBuffer);
   ByteBuffer temp=encode(outputData);
   buffer.position(temp.limit());
   buffer.compact();
   if(outputData.equalsIgnoreCase("bye\r\n")){
    key.cancel();
    socketChannel.close();
    System.out.println("stop connect with the host");
   }
  }
  
  public void receive(SelectionKey key)throws IOException{
   ByteBuffer buffer=(ByteBuffer)key.attachment();
   SocketChannel socketChannel=(SocketChannel)key.channel();
   ByteBuffer readBuffer=ByteBuffer.allocate(32);
   socketChannel.read(readBuffer);
   readBuffer.flip();
   buffer.limit(buffer.capacity());
   buffer.put(readBuffer);
   
  }
  
  public String decode(ByteBuffer buffer){
   CharBuffer charBuffer=charset.decode(buffer);
   return charset.toString();
  }
  public ByteBuffer encode(String str){
   return charset.encode(str);
  }
  
 public static void main(String[] args)throws Exception {
  // TODO 自动生成方法存根
        EchoServer server=new EchoServer();
        server.service();
 }}客户端部分
package network;
import java.io.*;
import java.nio.channels.*;
import java.nio.*;
import java.nio.charset.*;
import java.net.*;
import java.util.*;public class EchoClient {
    private SocketChannel socketChannel=null;
    private ByteBuffer sendBuffer=ByteBuffer.allocate(1024);
    private ByteBuffer receiveBuffer=ByteBuffer.allocate(1024);
    private Charset charset=Charset.forName("GBK");
    private Selector selector;
    
    public EchoClient()throws IOException {
     socketChannel=SocketChannel.open();
     InetAddress ia= InetAddress.getLocalHost();
     InetSocketAddress isa=new InetSocketAddress(ia,8000);
     socketChannel.connect(isa);
     socketChannel.configureBlocking(false);
     System.out.println("get connect successfully with server.");
     selector=Selector.open();
    } 
 /**
  * @param args
  */
 public static void main(String[] args) throws IOException{
  
  final EchoClient client=new EchoClient();
  Thread receiver=new Thread(){
   public void run(){
    client.receiveFromUser();
   }
  };
  receiver.start();
  client.talk(); }
 
 public void receiveFromUser(){
  try{
   BufferedReader localReader=new BufferedReader(new InputStreamReader(System.
in));
   String msg=null;
   while((msg=localReader.readLine())!=null){
    synchronized(sendBuffer){
     sendBuffer.put(encode(msg+"\r\n"));
    }
    if(msg.equalsIgnoreCase("bye"))
     break;
   }
  }
  catch(IOException e){
   e.printStackTrace();
  }
 }
 
 public void talk()throws IOException{
  socketChannel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE)
;
   while(selector.select()>0){
    Set readyKeys=selector.selectedKeys();
    Iterator it=readyKeys.iterator();
    while(it.hasNext()){
     SelectionKey key=null;
     try{
      key=(SelectionKey) it.next();
      it.remove();
      
     
      if(key.isReadable()){
       receive(key);
      }
      if(key.isWritable()){
       send(key);
      }
     }
     catch(IOException e){
      e.printStackTrace();
      try{
       if(key!=null){
        key.cancel();
        key.channel().close();
       }
      }
      catch(Exception ex){e.printStackTrace();}
     }
    }
    
   }
 }
 
  public void send(SelectionKey key)throws IOException{
  
   SocketChannel socketChannel=(SocketChannel)key.channel();
   synchronized(sendBuffer){
    sendBuffer.flip();
    socketChannel.write(sendBuffer);
    sendBuffer.compact();
   }
  }
  
  public void receive(SelectionKey key)throws IOException{
   
   SocketChannel socketChannel=(SocketChannel)key.channel();
      socketChannel.read(receiveBuffer);
   receiveBuffer.flip();
   String receiveData=decode(receiveBuffer);
   if(receiveData.indexOf("\n")==-1)return;
   String outputData=receiveData.substring(0,receiveData.indexOf("\n")+1);
   if(outputData.equalsIgnoreCase("echo:bye\r\n")){
    key.cancel();
    socketChannel.close();
    System.out.println("stop connect with the server");
    selector.close();
    System.exit(0);
   }
   ByteBuffer temp=encode(outputData);
   receiveBuffer.position(temp.limit());
   receiveBuffer.compact();
   
  }
  public String decode(ByteBuffer buffer){
   CharBuffer charBuffer=charset.decode(buffer);
   return charset.toString();
  }
  public ByteBuffer encode(String str){
   return charset.encode(str);
  }
 }
server控制台输出:server start
receive connet from: /192.168.88.34:1278
Exception in thread "main" java.nio.BufferOverflowException
 at java.nio.HeapByteBuffer.put(Unknown Source)
 at network.EchoServer.receive(EchoServer.java:103)
 at network.EchoServer.service(EchoServer.java:55)
 at network.EchoServer.main(EchoServer.java:118)
client控制台输出:
get connect successfully with server.
hi
java.io.IOException: 远程主机强迫关闭了一个现有的连接。
 at sun.nio.ch.SocketDispatcher.read0(Native Method)
 at sun.nio.ch.SocketDispatcher.read(Unknown Source)
 at sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source)
 at sun.nio.ch.IOUtil.read(Unknown Source)
 at sun.nio.ch.SocketChannelImpl.read(Unknown Source)
 at network.EchoClient.receive(EchoClient.java:108)
 at network.EchoClient.talk(EchoClient.java:74)
 at network.EchoClient.main(EchoClient.java:40)

解决方案 »

  1.   

    你的代码有问题,具体的我就不仔细看了,给你一个参考 http://www.java2000.net/viewthread.jsp?tid=4745
      

  2.   

      调试了下,终于帮LZ把错误给找出来了,并且运行成功!
          是"server部分"的这个方法有问题 
                   public void service() throws IOException {
    serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    int num = selector.select();//新加部分
    while (num > 0) {// 这里有错,应该先定义一个整形变量事先获得selector.select()的值,而不应该放在判断条件里面,既不能够放在while()里面。
    // while (true) {//也可以不用int num = selector.select();直接用死循环就OK了
    Set readyKeys = selector.selectedKeys();
    Iterator it = readyKeys.iterator();
    while (it.hasNext()) {
    SelectionKey key = null;
    try {
    key = (SelectionKey) it.next();
    it.remove();