下面的代码,暂时只要实现客户端发送一段String给server,就可以
服务器端输出:Listening the port 1098
可以被链接
isReadable
read:LOGIN:aaa&bbb
isReadable
java.io.IOException: 远程主机强迫关闭了一个现有的连接。
每次在关闭客户端
server好像总是多读一次,isReadable,因为读不到,导致IOException.
是不是client在退出时,SocketChannel要关闭?不过加了SocketChannel关闭的语句就死循环.//server
package com.rpc.nio;import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;
import java.util.Set;public class NioServer { private int port; private Selector selector; private ServerSocketChannel ssc; private ServerSocket server; private InetSocketAddress address; public NioServer() {
this(new InetSocketAddress(1098), 1098);
} public NioServer(InetSocketAddress address, int port) {
this.address = address;
this.port = port;
initServer();
} private void initServer() {
try {
ssc = ServerSocketChannel.open(); server = ssc.socket();
server.bind(address);
selector = Selector.open();
ssc.configureBlocking(false);
} catch (IOException e) {
e.printStackTrace();
}
}

public void startup()  throws IOException {
try {
ssc.register(selector, SelectionKey.OP_ACCEPT);
} catch (ClosedChannelException e) {
e.printStackTrace();
}
System.out.println("Listening the port "+port);

while (!Thread.interrupted()) {
int nKeys = selector.select();
if (nKeys <= 0) {
                continue;
}
Set readyKeys = selector.selectedKeys();
Iterator it = readyKeys.iterator();
while (it.hasNext()) {
SelectionKey key = (SelectionKey)it.next();
it.remove();
readyKeys.clear();
try {
if (key.isAcceptable()) {
System.out.println("可以被链接");
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
SocketChannel channel = ssc.accept();
channel.configureBlocking(false);
SelectionKey clientKey = channel.register(selector, SelectionKey.OP_READ);
}
if (key.isReadable()) {
System.out.println("isReadable");
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.read(buffer);
buffer.flip();

String checkBuffer = this.decode(buffer);
System.out.println("read:" + checkBuffer);
}
if (key.isWritable()) {
System.out.println("isWritable");
}
}catch (IOException ex) {
System.out.println(ex);
key.cancel();
try {
key.channel().close();
} catch (IOException cex) {
}
}
}

}
}

public String decode(ByteBuffer buffer) {
Charset charset = null;
CharsetDecoder decoder = null;
CharBuffer charBuffer = null;
try {
charset = Charset.forName("gb2312");
decoder = charset.newDecoder();
charBuffer = decoder.decode(buffer);
return charBuffer.toString();
} catch (Exception ex) {
ex.printStackTrace();
return "";
} }



public static void main(String[] args) {
NioServer server = new NioServer();
try {
server.startup();
} catch (IOException e) { e.printStackTrace();
}

}}
//client
package com.rpc.nio;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;import com.rpc.me.Client;public class NioClient { public SocketChannel client = null; public InetSocketAddress isa = null; public void connect()  {
try {
client = SocketChannel.open();

isa = new InetSocketAddress("127.0.0.1", 1098);
client.connect(isa);
System.out.println("connect...");
client.configureBlocking(false);
sendMessage();
} catch (Exception e) {
e.printStackTrace();
} }

public void sendMessage() throws IOException{
ByteBuffer buffer = ByteBuffer.allocate(1024);

String message = new String("LOGIN:" + "aaa" + "&" + "bbb");
buffer = ByteBuffer.wrap(message.getBytes());
while (buffer.hasRemaining() & client.write(buffer) != -1)
;
System.out.println(message + " has been send");
buffer.flip();

Charset charset = Charset.forName("gb2312");
CharsetDecoder decoder = charset.newDecoder();
CharBuffer charBuffer = decoder.decode(buffer);



} public static void main(String[] args) {
NioClient mmm = new NioClient();
mmm.connect();
}}

解决方案 »

  1.   

    我是想客户端关闭的时候,服务器不是用异常来知道.也就是不出现IO异常,可以吗?
    还是NIO就必须这样才能知道客户端关闭?
      

  2.   

    关闭的话就是一异常呀,正常的话,不会关,所以也可以说NIO必须这样才能知道客户端情况
      

  3.   


    普通IO好像关闭客户端没有什么异常的.如果我要实现客户端想发送消息时才链接Server,那靠异常来处理server不是很累?没基础,所以可能问题比较弱.
      

  4.   

    不是它的问题,你应当在if(,,,,)中加个continue;来越过下面的判断,然后再去while