为什么向ServerSocketChannel写入一条信息 却会产生两个Read事件 第一次全部读出写进去的信息 接着还会出现一个Read事件 不过这次读出的是空的 服务器:
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;public class Server implements Runnable
{
private int port;
private final ByteBuffer buffer = ByteBuffer.allocate( 16384 );
public Server( int port )
{
this.port = port;
new Thread( this ).start();
}
public void run()
{
try
{
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking( false );
ServerSocket ss = ssc.socket();
InetSocketAddress isa = new InetSocketAddress(
  "sunxiao.3322.org",port);
ss.bind( isa );
Selector selector = Selector.open();
ssc.register( selector, SelectionKey.OP_ACCEPT );
System.out.println( "Listening on port "+port );
while (true)
{
int num = selector.select();
System.out.println("Return Set Size: "+num);
if (num == 0)
continue;
Set keys = selector.selectedKeys();
Iterator it = keys.iterator();
while (it.hasNext())
{
SelectionKey key = (SelectionKey)it.next();
it.remove();
             if(key.isAcceptable())
             {
             System.out.println( "accept-----" );
             Socket s = ss.accept();
             System.out.println( "Got connection from "+s );
             SocketChannel sc = s.getChannel();
             sc.configureBlocking( false );
             sc.register( selector, SelectionKey.OP_READ );
             }
             else if(key.isReadable())
             {
             System.out.println("Read-----");
             SocketChannel sc = null;
             try
             {
             sc = (SocketChannel)key.channel();
             boolean ok = processInput( sc );
             if(!ok)
             {
             key.cancel();
             Socket s = null;
             try
             {
             s = sc.socket();
             s.close();
             }
             catch( IOException ie )
             {
             System.err.println("Error closing socket "
               +s+": "+ie );
             }
             }
             }
             catch(IOException ie)
             {
             key.cancel();
             try
             {
             sc.close();
             }
             catch(IOException ie2)
             {
             System.out.println( ie2 );
             }
             System.out.println( "Closed "+sc );
             }
             }
             }
             System.out.println("");
             //keys.clear();
            }
        }
        catch(IOException ie)
        {
         System.err.println( ie );
        }
    }
    private boolean processInput( SocketChannel sc ) throws IOException {
    System.err.println("加密处理");
    buffer.clear();
    sc.read( buffer );
    buffer.flip();    // If no data, close the connection
    if (buffer.limit()==0) {
      return false;
    }    // Simple rot-13 encryption
    for (int i=0; i<buffer.limit(); ++i) {
      byte b = buffer.get( i );      if ((b>='a' && b<='m') || (b>='A' && b<='M')) {
        b += 13;
      } else if ((b>='n' && b<='z') || (b>='N' && b<='Z')) {
        b -= 13;
      }
      try{Thread.sleep(3000);}catch(Exception e){};
      buffer.put( i, b );
    }
    sc.write( buffer );    System.out.println( "Processed "+buffer.limit()+" from "+sc );    return true;
  }  static public void main( String args[] ) throws Exception
  {
   new Server(2567);
  }
}客户端:import java.nio.*;
import java.nio.channels.*;
import java.net.*;
import java.io.*;
import java.nio.charset.*;public class NioClient
{
SocketChannel sc=null;
InetSocketAddress isa;
public NioClient(int port)
{
try
{
isa=new InetSocketAddress("sunxiao.3322.org",port);
sc=SocketChannel.open();
sc.connect(isa);
try{Thread.sleep(3000);}catch(Exception e){};
String s="abcd";
CharBuffer cb=CharBuffer.wrap(s);
Charset latin1=Charset.forName("ISO-8859-1");
CharsetEncoder encoder=latin1.newEncoder();
ByteBuffer bb=encoder.encode(cb);
printInfoByte(bb);
sc.write(bb);

ByteBuffer bb1=ByteBuffer.allocate(1024);
sc.read(bb1);
bb1.flip();
CharsetDecoder decoder = latin1.newDecoder();
CharBuffer cb1=CharBuffer.allocate(512);
decoder.decode(bb1,cb1,false);
cb1.flip();
printInfo(cb1);
System.out.println(cb1);
}
catch(IOException e)
{
System.out.println("/"+e);
}
finally
{
if(sc!=null)
try{sc.close();}catch(IOException e){}
}
}
private void printInfo(CharBuffer bb)
{
System.out.println(bb.position()+"/"+bb.limit()+"/"+bb.capacity());
}
private void printInfoByte(ByteBuffer bb)
{
System.out.println(bb.position()+"/"+bb.limit()+"/"+bb.capacity());
}
public static void main(String sun[])
{
new NioClient(2567);
}
}