processSelectionKey(selKey);
} catch (IOException e) {
// 处理异常
selKey.cancel();
}
}
}
}
public static void processSelectionKey(SelectionKey selKey) throws IOException {
ByteBuffer buf = ByteBuffer.allocateDirect(1024);
// 确认连接正常
if (selKey.isValid() && selKey.isConnectable()) {
// 得到通道
SocketChannel sChannel = (SocketChannel) selKey.channel();
// 是否连接完毕?
boolean success = sChannel.finishConnect();
if (!success) {
// 异常
selKey.cancel();
}
}
// 如果可以读取数据
if (selKey.isValid() && selKey.isReadable()) {
// 得到通道
SocketChannel sChannel = (SocketChannel) selKey.channel();
if (sChannel.read(buf) > 0) {
// 转到最开始
buf.flip();
while (buf.remaining() > 0) {
System.out.print((char) buf.get());
}
// 也可以转化为字符串,不过需要借助第三个变量了。
// buf.get(buff, 0, numBytesRead);
// System.out.println(new String(buff, 0, numBytesRead, "UTF-8"));
// 复位,清空
buf.clear();
}
}
// 如果可以写入数据
if (selKey.isValid() && selKey.isWritable()) {
// 得到通道
SocketChannel sChannel = (SocketChannel) selKey.channel();
// 区分2个侦听器的关键字
// 我这里只写一次数据。
if (!s1 && key1.equals(selKey)) {
System.out.println("channel1 write data..");
buf.clear();
buf.put("HELO localhost\n".getBytes());
buf.flip();
sChannel.write(buf);
s1 = true;
} else if (!s2 && key2.equals(selKey)) {
System.out.println("channel2 write data..");
buf.clear();
buf.put("HELO localhost\n".getBytes());
buf.flip();
sChannel.write(buf);
s2 = true;
}
}
}
// 判断已经写过数据的标志
static boolean s1 = false;
static boolean s2 = false;
}
一个运行的效果
channel1 write data..
220 Coremail SMTP(Anti Spam) System (163net[040302])
250 bjfee_app2
channel2 write data..
220 csdn.net ESMTP "can't tell you"
250 csdn.net
结论
这样做,我们的多个数据通道就可以统一管理,分别处理器读写操作。
责任编辑:小草