public classTimeClient {public static voidmain(String[] args) {int port = 8080;new Thread(new TimeClientHandle("127.0.0.1", port), "TimeClient-001").start();
}
}public class TimeClientHandle implementsRunnable {privateString host;private intport;privateSelector selector;privateSocketChannel socketChannel;private volatile booleanstop;public TimeClientHandle(String host, intport) {this.host = host == null ? "127.0.0.1": host;this.port =port;try{
selector=Selector.open();
socketChannel=SocketChannel.open();
socketChannel.configureBlocking(false);
}catch(IOException e) {
e.printStackTrace();
System.exit(1);
}
}
@Overridepublic voidrun() {try{
doConnect();
}catch(IOException e) {
e.printStackTrace();
System.exit(1);
}while (!stop) {try{
selector.select(1000);
Set selectedKeys =selector.selectedKeys();
Iterator it =selectedKeys.iterator();
SelectionKey key= null;while(it.hasNext()) {
key=it.next();
it.remove();try{
handleInput(key);
}catch(Exception e) {if (key != null) {
key.cancel();if (key.channel() != null)
key.channel().close();
}
}
}
}catch(Exception e) {
e.printStackTrace();
System.exit(1);
}
}//多路复用器关闭后,所有注册在上面的Channel和Pipe等资源都会被自动去注册并关闭,所以不需要重复释放资源
if (selector != null)try{
selector.close();
}catch(IOException e) {
e.printStackTrace();
}
}private void doConnect() throwsIOException {//如果直接连接成功,则注册到多路复用器上,发送请求消息,读应答
if (!socketChannel.connect(newInetSocketAddress(host, port))) {
socketChannel.register(selector, SelectionKey.OP_READ);
doWrite(socketChannel);
}else//没有直接连接成功,不代表失败,而是说明服务器还没有返回TCP握手的应答消息,所以注册OP_CONNECT事件,监听消息。
socketChannel.register(selector, SelectionKey.OP_CONNECT); }private void handleInput(SelectionKey key) throwsIOException {if(key.isValid()) {//判断是否连接成功
SocketChannel sc =(SocketChannel) key.channel();if (key.isConnectable()) {//判断是否有连接事件,是的话,说明未连接
if (sc.finishConnect()) {//再连接
sc.register(selector, SelectionKey.OP_READ);
doWrite(sc);
}elseSystem.exit(1);//连接失败,进程退出
}if(key.isReadable()) {
ByteBuffer readBuffer= ByteBuffer.allocate(1024);int readBytes =sc.read(readBuffer);if (readBytes > 0) {
readBuffer.flip();byte[] bytes = new byte[readBuffer.remaining()];
readBuffer.get(bytes);
String body= new String(bytes, "UTF-8");
System.out.println("Now is : " +body);this.stop = true;
}else if (readBytes < 0) {//对端链路关闭
key.cancel();
sc.close();
}
}
}
}private void doWrite(SocketChannel sc) throwsIOException {byte[] req = "QUERY TIME ORDER".getBytes();
ByteBuffer writeBuffer=ByteBuffer.allocate(req.length);
writeBuffer.put(req);
writeBuffer.flip();
sc.write(writeBuffer);if (!writeBuffer.hasRemaining())
System.out.println("Send order 2 server succeed.");
}
}