NIO的奇怪事件 非常奇怪! 救救我!_!

sunkdjxiao發表於2004-04-17
下面一個客戶端程式碼(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);
}
}

相關文章