在客户端主动关闭连接之后,按理说服务端在调用Selector的select方法时候应该是阻塞的,但是我的测试代码中却仍然能够返回,而且返回的SelectionKey的isReadable方法返回的仍然是key,但是通道中的数据已经被读取过了。不知道是不是我的客户端代码有问题,还是服务端有问题。服务端的代码使用了Recator模式,请帮忙看看。谢谢!下面是服务端的代码
[code]
package snake.test.n4;import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.util.Iterator;
import java.util.Set;public class N4 { static int port = 6666; Selector selector;
ServerSocketChannel serverSocket; public static void main(String[] args) {
try {
ServerSocketChannel ssc = ServerSocketChannel.open(); ServerSocket ss = ssc.socket();
InetSocketAddress isa = new InetSocketAddress(port);
ss.bind(isa); Dispatcher d1 = new Dispatcher();
Dispatcher d2 = new Dispatcher(); String name = "a1";
Acceptor a1 = new Acceptor(ssc, d1, name);
name = "a2";
Acceptor a2 = new Acceptor(ssc, d2, name); new Thread(d1).start();
new Thread(d2).start();
new Thread(a1).start();
new Thread(a2).start();
} catch (IOException e) {
e.printStackTrace();
} } void run() { }}package snake.test.n4;import java.nio.channels.SelectionKey;public interface Handler {
void handle(SelectionKey key);
}
package snake.test.n4;import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;public class Acceptor implements Runnable { private ServerSocketChannel ssc;
private Dispatcher d; private int num = 0; private String name; public Acceptor(ServerSocketChannel ssc, Dispatcher d, String name) {
this.ssc = ssc;
this.d = d;
this.name = name;
} public void run() { for (;;) { try { num++;
SocketChannel sc; sc = ssc.accept(); sc.configureBlocking(false);
d.register(sc, SelectionKey.OP_READ, new RequestHandler(sc,
name + num));
} catch (IOException e) {
e.printStackTrace();
break;
} } }}
package snake.test.n4;import java.io.IOException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;
import java.util.Set;public class Dispatcher implements Runnable {
private Selector sel; private Object gate = new Object(); public Dispatcher() {
try {
sel = Selector.open();
} catch (IOException e) {
e.printStackTrace();
}
} void dispatch() throws IOException { sel.select(); for (Iterator<SelectionKey> i = sel.selectedKeys().iterator(); i
.hasNext();) {
SelectionKey sk = i.next();
i.remove();
Handler h = (Handler) sk.attachment();
h.handle(sk);
} synchronized (gate) { } } void register(SelectableChannel ch, int ops, Handler h) {
try {
synchronized (gate) {
sel.wakeup();
ch.register(sel, ops, h);
} } catch (ClosedChannelException e) {
e.printStackTrace();
}
} public void run() {
for (;;) {
try {
dispatch();
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}}
package snake.test.n4;import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;public class RequestHandler implements Handler { private SocketChannel sc; String name; public RequestHandler(SocketChannel sc, String name) {
this.sc = sc;
this.name = name;
} public void handle(SelectionKey sk) { sc = (SocketChannel) sk.channel();
String recvData = null;
try {
recvData = readMessage();
System.out.println(name + " " + recvData);
} catch (IOException e) {
sk.cancel();
System.out.println("Closed");
} } public String readMessage() throws IOException {
String result = null; ByteBuffer buf = ByteBuffer.allocate(16384);
buf.clear();
int nBytes = sc.read(buf); buf.flip(); // Charset charset = Charset.forName("us-ascii");
Charset charset = Charset.forName(System.getProperty("file.encoding"));
CharsetDecoder decoder = charset.newDecoder();
CharBuffer charBuffer = decoder.decode(buf);
result = charBuffer.toString(); // sc.write(buf); return result;
}
}[/code]
下面是客户端的代码[code]package snake.test.channel;import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Date;import java.io.*;public class sendMsg { public static void main(String[] args) { try { Socket theSocket = new Socket("127.0.0.1", 6666);
Writer out = new OutputStreamWriter(theSocket.getOutputStream());
Date now = new Date();
out.write(now.toString() + "\r\n");
out.flush();
theSocket.close();
} // end try catch (UnknownHostException ex) { System.err.println(ex); } catch (IOException ex) { System.err.println(ex); } }
} [/code]在运行服务端之后,客户端向服务端发送了当前的时间,结果服务端的输出如下
a11 Mon Oct 22 20:38:47 CST 2007a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
请问怎么解决这个问题??
谢谢!
[code]
package snake.test.n4;import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.util.Iterator;
import java.util.Set;public class N4 { static int port = 6666; Selector selector;
ServerSocketChannel serverSocket; public static void main(String[] args) {
try {
ServerSocketChannel ssc = ServerSocketChannel.open(); ServerSocket ss = ssc.socket();
InetSocketAddress isa = new InetSocketAddress(port);
ss.bind(isa); Dispatcher d1 = new Dispatcher();
Dispatcher d2 = new Dispatcher(); String name = "a1";
Acceptor a1 = new Acceptor(ssc, d1, name);
name = "a2";
Acceptor a2 = new Acceptor(ssc, d2, name); new Thread(d1).start();
new Thread(d2).start();
new Thread(a1).start();
new Thread(a2).start();
} catch (IOException e) {
e.printStackTrace();
} } void run() { }}package snake.test.n4;import java.nio.channels.SelectionKey;public interface Handler {
void handle(SelectionKey key);
}
package snake.test.n4;import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;public class Acceptor implements Runnable { private ServerSocketChannel ssc;
private Dispatcher d; private int num = 0; private String name; public Acceptor(ServerSocketChannel ssc, Dispatcher d, String name) {
this.ssc = ssc;
this.d = d;
this.name = name;
} public void run() { for (;;) { try { num++;
SocketChannel sc; sc = ssc.accept(); sc.configureBlocking(false);
d.register(sc, SelectionKey.OP_READ, new RequestHandler(sc,
name + num));
} catch (IOException e) {
e.printStackTrace();
break;
} } }}
package snake.test.n4;import java.io.IOException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;
import java.util.Set;public class Dispatcher implements Runnable {
private Selector sel; private Object gate = new Object(); public Dispatcher() {
try {
sel = Selector.open();
} catch (IOException e) {
e.printStackTrace();
}
} void dispatch() throws IOException { sel.select(); for (Iterator<SelectionKey> i = sel.selectedKeys().iterator(); i
.hasNext();) {
SelectionKey sk = i.next();
i.remove();
Handler h = (Handler) sk.attachment();
h.handle(sk);
} synchronized (gate) { } } void register(SelectableChannel ch, int ops, Handler h) {
try {
synchronized (gate) {
sel.wakeup();
ch.register(sel, ops, h);
} } catch (ClosedChannelException e) {
e.printStackTrace();
}
} public void run() {
for (;;) {
try {
dispatch();
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}}
package snake.test.n4;import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;public class RequestHandler implements Handler { private SocketChannel sc; String name; public RequestHandler(SocketChannel sc, String name) {
this.sc = sc;
this.name = name;
} public void handle(SelectionKey sk) { sc = (SocketChannel) sk.channel();
String recvData = null;
try {
recvData = readMessage();
System.out.println(name + " " + recvData);
} catch (IOException e) {
sk.cancel();
System.out.println("Closed");
} } public String readMessage() throws IOException {
String result = null; ByteBuffer buf = ByteBuffer.allocate(16384);
buf.clear();
int nBytes = sc.read(buf); buf.flip(); // Charset charset = Charset.forName("us-ascii");
Charset charset = Charset.forName(System.getProperty("file.encoding"));
CharsetDecoder decoder = charset.newDecoder();
CharBuffer charBuffer = decoder.decode(buf);
result = charBuffer.toString(); // sc.write(buf); return result;
}
}[/code]
下面是客户端的代码[code]package snake.test.channel;import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Date;import java.io.*;public class sendMsg { public static void main(String[] args) { try { Socket theSocket = new Socket("127.0.0.1", 6666);
Writer out = new OutputStreamWriter(theSocket.getOutputStream());
Date now = new Date();
out.write(now.toString() + "\r\n");
out.flush();
theSocket.close();
} // end try catch (UnknownHostException ex) { System.err.println(ex); } catch (IOException ex) { System.err.println(ex); } }
} [/code]在运行服务端之后,客户端向服务端发送了当前的时间,结果服务端的输出如下
a11 Mon Oct 22 20:38:47 CST 2007a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
a11
请问怎么解决这个问题??
谢谢!
解决方案 »
- 如何更新终端上文件
- Java中关于是组件透明,使得图片背景显示的问题
- 各位达人,请问我怎么能够从JVM中读取加载的某个包的结构,谢谢!
- 请问,如何画仪表盘(要能够修改表针的粗细)?谢谢
- 请假乱码问题
- 100分求教:Java中引用其他类数量和.class文件大小关系?
- 做个带界面的版本升级工具是java好还是VC好
- 小弟跪求:JAVA中如何读取PPT文件中的内容。这个问题困扰我很久了,希望大家能够给我帮助。分,不是问题。来者都有分!!!
- 关于引用变量的赋值问题,请高手指教,有分!
- Java byte转中文乱码
- 设置windows风格时,为什么说找不到com.sun.java.swing.plaf.windows.windowsLookAndFeel呢?
- 请问下设计模式那本书比较好啊?
代码没贴上,重新帖[code]
package snake.test.n4;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.util.Iterator;
import java.util.Set;
public class N4 {
static int port = 6666;
Selector selector;
ServerSocketChannel serverSocket;
public static void main(String[] args) {
try {
ServerSocketChannel ssc = ServerSocketChannel.open();
ServerSocket ss = ssc.socket();
InetSocketAddress isa = new InetSocketAddress(port);
ss.bind(isa);
Dispatcher d1 = new Dispatcher();
Dispatcher d2 = new Dispatcher();
String name = "a1";
Acceptor a1 = new Acceptor(ssc, d1, name);
name = "a2";
Acceptor a2 = new Acceptor(ssc, d2, name);
new Thread(d1).start();
new Thread(d2).start();
new Thread(a1).start();
new Thread(a2).start();
} catch (IOException e) {
e.printStackTrace();
}
}
void run() {
}
}
package snake.test.n4;
import java.nio.channels.SelectionKey;
public interface Handler {
void handle(SelectionKey key);
}
package snake.test.n4;
import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class Acceptor implements Runnable {
private ServerSocketChannel ssc;
private Dispatcher d;
private int num = 0;
private String name;
public Acceptor(ServerSocketChannel ssc, Dispatcher d, String name) {
this.ssc = ssc;
this.d = d;
this.name = name;
}
public void run() {
for (;;) {
try {
num++;
SocketChannel sc;
sc = ssc.accept();
sc.configureBlocking(false);
d.register(sc, SelectionKey.OP_READ, new RequestHandler(sc,
name + num));
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
}
package snake.test.n4;
import java.io.IOException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;
import java.util.Set;
public class Dispatcher implements Runnable {
private Selector sel;
private Object gate = new Object();
public Dispatcher() {
try {
sel = Selector.open();
} catch (IOException e) {
e.printStackTrace();
}
}
void dispatch() throws IOException {
sel.select();
for (Iterator<SelectionKey> i = sel.selectedKeys().iterator(); i
.hasNext();) {
SelectionKey sk = i.next();
i.remove();
Handler h = (Handler) sk.attachment();
h.handle(sk);
}
synchronized (gate) {
}
}
void register(SelectableChannel ch, int ops, Handler h) {
try {
synchronized (gate) {
sel.wakeup();
ch.register(sel, ops, h);
}
} catch (ClosedChannelException e) {
e.printStackTrace();
}
}
public void run() {
for (;;) {
try {
dispatch();
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
}
package snake.test.n4;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
public class RequestHandler implements Handler {
private SocketChannel sc;
String name;
public RequestHandler(SocketChannel sc, String name) {
this.sc = sc;
this.name = name;
}
public void handle(SelectionKey sk) {
sc = (SocketChannel) sk.channel();
String recvData = null;
try {
recvData = readMessage();
System.out.println(name + " " + recvData);
} catch (IOException e) {
sk.cancel();
System.out.println("Closed");
}
}
public String readMessage() throws IOException {
String result = null;
ByteBuffer buf = ByteBuffer.allocate(16384);
buf.clear();
int nBytes = sc.read(buf);
buf.flip();
// Charset charset = Charset.forName("us-ascii");
Charset charset = Charset.forName(System.getProperty("file.encoding"));
CharsetDecoder decoder = charset.newDecoder();
CharBuffer charBuffer = decoder.decode(buf);
result = charBuffer.toString();
// sc.write(buf);
return result;
}
}
[/code]下面是客户端的代码
[code]
package snake.test.channel;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.io.*;
public class sendMsg {
public static void main(String[] args) {
try {
Socket theSocket = new Socket("127.0.0.1", 6666);
Writer out = new OutputStreamWriter(theSocket.getOutputStream());
Date now = new Date();
out.write(now.toString() + "\r\n");
out.flush();
theSocket.close();
} // end try
catch (UnknownHostException ex) {
System.err.println(ex);
}
catch (IOException ex) {
System.err.println(ex);
}
}
}
[/code]
try{
Selector selector=Selector.open();
InetSocketAddress isa=new InetSocketAddress("www.ah.xinhuanet.com",80);
SocketChannel sc=SocketChannel.open(isa);
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_WRITE|SelectionKey.OP_READ);
int keyn;
while((keyn=selector.select())>0){
Set readykey=selector.selectedKeys();
Iterator it=readykey.iterator();
while(it.hasNext()){
SelectionKey skey=(SelectionKey)it.next();
it.remove();
SocketChannel scc=(SocketChannel)skey.channel();
if((skey.readyOps()&SelectionKey.OP_WRITE)==SelectionKey.OP_WRITE){
System.out.println("ddd1");
if(!scc.isConnected()) break;
String head="GET / HTTP/1.1\r\n" +
"Connection: close\r\n" +
"Host: www.ah.xinhuanet.net\r\n" +
"\r\n";
ByteBuffer bbf=ByteBuffer.wrap(head.getBytes());
scc.write(bbf);
//scc.close();
}
if((skey.readyOps()&SelectionKey.OP_READ)==SelectionKey.OP_READ){
System.out.println("ddd2");
ByteBuffer bff=ByteBuffer.allocate(1024);
bff.flip();
int n=scc.read(bff);
if(n>0&&n==bff.limit()){
System.out.print(bff.toString());
}
}
}
readykey.clear();
}
}catch(IOException e){
e.printStackTrace();
}
}还有 就是 scc.write(bbf); 的时候,出异常。不知道了
http://mina.apache.org