三、应用范例
服务端代码:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
class AsyncServer implements Runnable {
private ByteBuffer r_buff = ByteBuffer.allocate(1024);
private ByteBuffer w_buff = ByteBuffer.allocate(1024);
private static int port = 8848;
public AsyncServer() {
new Thread(this).start();
}
private void info(String str){
System.out.println(str);
}
public void run() {
try {
Selector s = Selector.open(); 生成一个信号监视器
ServerSocketChannel ssc = ServerSocketChannel.open(); // 生成一个侦听端
ssc.configureBlocking(false);// 将侦听端设为异步方式
// 侦听端绑定到一个端口
ssc.socket().bind(new InetSocketAddress(port));
ssc.register(s, SelectionKey.OP_ACCEPT,new NetEventHandler());// 设置侦听端所选的异步信号OP_ACCEPT
info("开始启动服务器");
while (true) {
int n = s.select(100);
if (n == 0) {// 没有指定的I/O事件发生
continue;
}
Set<SelectionKey> readys = s.selectedKeys();
if(readys.size() == 0){
continue;
}
while (readys.iterator().hasNext()) {
SelectionKey key = readys.iterator().next();
if (key.isAcceptable()) {// 侦听端信号触发
info("侦听端信号触发");
ServerSocketChannel server = (ServerSocketChannel) key.channel();
SocketChannel sc = server.accept();
sc.configureBlocking(false);
sc.register(s, SelectionKey.OP_READ,new NetEventHandler());
}
if (key.isReadable()) {// 某socket可读信号
DealwithData(key);
}
readys.iterator().remove();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void DealwithData(SelectionKey key) throws IOException {
NetEventHandler eventHandler = (NetEventHandler)key.attachment();
info("eventHandler:" + eventHandler);
// 由key获取指定socketchannel的引用
SocketChannel sc = (SocketChannel) key.channel();
r_buff.clear();
int count;
while ((count = sc.read(r_buff)) > 0);
// 将r_buff内容拷入w_buff
r_buff.flip();
w_buff.clear();
w_buff.put(r_buff);
w_buff.flip();
// 将数据返回给客户端
EchoToClient(sc);
w_buff.clear();
r_buff.clear();
}
public void EchoToClient(SocketChannel sc) throws IOException {
while (w_buff.hasRemaining())
sc.write(w_buff);
}
public static void main(String args[]) {
if (args.length > 0) {
port = Integer.parseInt(args[0]);
}
new AsyncServer();
}
}
客户端代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
class AsyncClient {
private SocketChannel sc;
private final int MAX_LENGTH = 1024;
private ByteBuffer r_buff = ByteBuffer.allocate(MAX_LENGTH);
private ByteBuffer w_buff = ByteBuffer.allocate(MAX_LENGTH);
private static String host ;
private static int port = 8848;
public AsyncClient() {
try {
InetSocketAddress addr = new InetSocketAddress(host, port);
// 生成一个socketchannel
sc = SocketChannel.open();
// 连接到server
sc.connect(addr);
while (!sc.finishConnect())
;
System.out.println("connection has been established!...");
while (true) {
// 回射消息
String echo;
try {
System.err.println("Enter msg you'd like to send: ");
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
// 输入回射消息
echo = br.readLine();
// 把回射消息放入w_buff中
w_buff.clear();
w_buff.put(echo.getBytes());
w_buff.flip();
} catch (IOException ioe) {
System.err.println("sth. is wrong with br.readline() ");
}
// 发送消息
while (w_buff.hasRemaining())
sc.write(w_buff);
w_buff.clear();
// 进入接收状态
Rec();
// 间隔1秒
Thread.currentThread().sleep(1000);
}
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
public void Rec() throws IOException {
int count;
r_buff.clear();
count = sc.read(r_buff);
r_buff.flip();
byte[] temp = new byte[r_buff.limit()];
r_buff.get(temp);
System.out.println("reply is " + count + " long, and content is: "
+ new String(temp));
}
public static void main(String args[]) {
if (args.length < 1) {// 输入需有主机名或IP地址
try {
System.err.println("Enter host name: ");
BufferedReader br = new BufferedReader(new InputStreamReader(
System.in));
host = br.readLine();
} catch (IOException ioe) {
System.err.println("sth. is wrong with br.readline() ");
}
} else if (args.length == 1) {
host = args[0];
} else if (args.length > 1) {
host = args[0];
port = Integer.parseInt(args[1]);
}
new AsyncClient();
}
}