NIO的奇怪事件 非常奇怪! 救救我!_!
下面一个客户端代码(NioClient)一个服务器端代码(NioServer)
先运行NioServer 再运行NioClient 第一次正常 但隐藏着3个奇怪的地方:
1:
一关闭NioClient(NioServer还开着), NioServer又会发现一个SelectionKey.OP_READ事件,就是原先那个处理过的事件,都不知道为什么?
2:
一关闭NioServer(NioClient还开着),NioClient又会发现无数个SelectionKey.OP_READ事件(永远不会停止),都是原先那个处理过的事件,又都不知道为什么?
3:
关闭所有的重新开始;先开一个NioServer和一个NioClient(都不要关掉),再开个NioClient,这时第二个开的NioClient会发现无数个SelectionKey.OP_READ事件(永远不会停止),也都是原先那个处理过的事件,又又都不知道为什么?
气炸了 希望高手指点 超谢
import java.io.*;
import java.util.*;
import java.net.*;
import java.nio.*;
import java.nio.charset.*;
import java.nio.channels.*;
public class NioServer
{
Charset charset=Charset.forName("gbk");
CharsetDecoder decoder=charset.newDecoder();
CharsetEncoder encoder=charset.newEncoder();
Selector selector;
ServerSocketChannel server;
ByteBuffer bBuffer=ByteBuffer.allocate(1024);
CharBuffer cBuffer=CharBuffer.allocate(1024);
public NioServer(int port)
{
try
{
selector=Selector.open();
server = ServerSocketChannel.open();
server.configureBlocking(false);
InetSocketAddress isa=new InetSocketAddress(
InetAddress.getLocalHost(),port);
server.socket().bind(isa);
server.register(selector,SelectionKey.OP_ACCEPT);
System.out.println("服务器启动!");
service();
}
catch(IOException e)
{
System.out.println(e);
}
}
public void service()throws IOException
{
while(true)
{
if(selector.select()<=0)
continue;
Set readyKeys=selector.selectedKeys();
Iterator i=readyKeys.iterator();
while(i.hasNext())
{
SelectionKey key=(SelectionKey)i.next();
i.remove();
if(key.isAcceptable())
{
System.out.println("isAcceptable()");
ServerSocketChannel keyChannel=(ServerSocketChannel)
key.channel();
SocketChannel sc=(SocketChannel)keyChannel.accept();
sc.configureBlocking(false);
sc.register(selector,SelectionKey.OP_READ);
}
else if(key.isReadable())
{
System.out.println("isReadable()");
SocketChannel keyChannel=(SocketChannel)key.channel();
keyChannel.read(bBuffer);
bBuffer.flip();
decoder.decode(bBuffer, cBuffer, false);
cBuffer.flip();
System.out.println("客户端:"+cBuffer+"服务器端:响应!");
String s="响应!";
keyChannel.write(encoder.encode(cBuffer.wrap(s)));
}
else if(key.isConnectable())
{
System.out.println("isConnectable()");
}
else if(key.isWritable())
{
System.out.println("isWritable()");
}
else if(key.isValid())
{
System.out.println("key.isValid()");
}
}
}
}
public static void main(String sun[])
{
new NioServer(10000);
}
}
import java.io.*;
import java.util.*;
import java.net.*;
import java.nio.*;
import java.nio.charset.*;
import java.nio.channels.*;
public class NioClient
{
Charset charset=Charset.forName("gbk");
CharsetDecoder decoder=charset.newDecoder();
CharsetEncoder encoder=charset.newEncoder();
Selector selector;
SocketChannel client;
ByteBuffer bBuffer=ByteBuffer.allocate(1024);
CharBuffer cBuffer=CharBuffer.allocate(1024);
public NioClient(int port)
{
try
{
selector=Selector.open();
InetSocketAddress isa=new InetSocketAddress(
InetAddress.getLocalHost(),port);
client=SocketChannel.open();
client.configureBlocking(false);
client.connect(isa);
client.register(selector,SelectionKey.OP_CONNECT |
SelectionKey.OP_READ);
System.out.println("客户端启动!");
service();
}
catch(IOException e)
{
System.out.println(e);
}
}
public void service()throws IOException
{
while(true)
{
if(selector.select()<=0)
continue;
Set readyKeys=selector.selectedKeys();
System.out.println("事件:"+readyKeys.size());
Iterator i=readyKeys.iterator();
while(i.hasNext())
{
SelectionKey key=(SelectionKey)i.next();
i.remove();
if(key.isAcceptable())
{
System.out.println("isAcceptable()");
}
else if(key.isReadable())
{
System.out.println("isReadable()");
SocketChannel keyChannel=(SocketChannel)key.channel();
keyChannel.read(bBuffer);
bBuffer.flip();
decoder.decode(bBuffer, cBuffer, false);
cBuffer.flip();
System.out.println(cBuffer);
}
else if(key.isConnectable())
{
System.out.println("isConnectable()");
SocketChannel keyChannel=(SocketChannel)key.channel();
if(keyChannel.isConnectionPending())
keyChannel.finishConnect();
String s="请求!";
keyChannel.write(encoder.encode(cBuffer.wrap(s)));
}
else if(key.isWritable())
{
System.out.println("isWritable()");
}
else if(key.isValid())
{
System.out.println("key.isValid()");
}
}
}
}
public static void main(String sun[])
{
new NioClient(10000);
}
}