为什么向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);
}
}
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);
}
}
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货